home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / public / bit / src / mpeg / video.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  107KB  |  3,971 lines

  1. /*
  2.  * Copyright (c) 1992 The Regents of the University of California.
  3.  * All rights reserved.  
  4.  *
  5.  * Permission to use, copy, modify, and distribute this software and its
  6.  * documentation for any purpose, without fee, and without written agreement is
  7.  * hereby granted, provided that the above copyright notice and the following
  8.  * two paragraphs appear in all copies of this software.
  9.  *
  10.  * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
  11.  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
  12.  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
  13.  * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  14.  *
  15.  * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
  16.  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
  17.  * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
  18.  * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
  19.  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  20.  *
  21.  * Hacked by T.C.Zhao (zhao@monte.svec.uh.edu) to get 1 frame at a time.
  22.  * Safer DestroyVidStream
  23.  */
  24. /* This file contains C code that implements
  25.  * the video decoder model.
  26.  */
  27.  
  28. #include <stdio.h>
  29. #include <stdlib.h>
  30. #include <assert.h>
  31.  
  32. #include "decoders.h"
  33. #include "video.h"
  34. #include "util.h"
  35. #include "proto.h"
  36.  
  37. /* Declarations of functions. */
  38. static void ReconIMBlock P((VidStream *, int));
  39. static void ReconPMBlock P((VidStream *, int, int, int, int));
  40. static void ReconBMBlock P((VidStream *, int, int, int, int));
  41. static void ReconBiMBlock P((VidStream *, int, int, int, int, int, int));
  42. static void ReconSkippedBlock P((unsigned char *, unsigned char*, int,
  43.                      int, int, int, int, int, int, int));
  44. static int DoPictureDisplay P((VidStream *));
  45. static int ParseSeqHead P((VidStream *));
  46. static int ParseGOP P((VidStream *));
  47. static int ParsePicture P((VidStream *, TimeStamp));
  48. static int ParseSlice P((VidStream *));
  49. static int ParseMacroBlock P((VidStream *));
  50. static void ProcessSkippedPFrameMBlocks P((VidStream *));
  51. static void ProcessSkippedBFrameMBlocks P((VidStream *));
  52.  
  53. extern int ditherType;
  54. char *ditherFlags;
  55.  
  56. /* Macro for returning 1 if num is positive, -1 if negative, 0 if 0. */
  57.  
  58. #define Sign(num) ((num > 0) ? 1 : ((num == 0) ? 0 : -1))
  59.  
  60. /* Declare global pointer to vid stream used for current decoding. */
  61.  
  62. VidStream *curVidStream = NULL;
  63.  
  64. /* Set up array for fast conversion from zig zag order to row/column
  65.    coordinates.
  66. */
  67.  
  68. int zigzag[64][2] = {
  69.   {0, 0}, {1, 0}, {0, 1}, {0, 2}, {1, 1}, {2, 0},
  70.   {3, 0}, {2, 1}, {1, 2}, {0, 3}, {0, 4}, {1, 3},
  71.   {2, 2}, {3, 1}, {4, 0}, {5, 0}, {4, 1}, {3, 2},
  72.   {2, 3}, {1, 4}, {0, 5}, {0, 6}, {1, 5}, {2, 4},
  73.   {3, 3}, {4, 2}, {5, 1}, {6, 0}, {7, 0}, {6, 1},
  74.   {5, 2}, {4, 3}, {3, 4}, {2, 5}, {1, 6}, {0, 7},
  75.   {1, 7}, {2, 6}, {3, 5}, {4, 4}, {5, 3}, {6, 2},
  76.   {7, 1}, {7, 2}, {6, 3}, {5, 4}, {4, 5}, {3, 6},
  77.   {2, 7}, {3, 7}, {4, 6}, {5, 5}, {6, 4}, {7, 3}, 
  78.   {7, 4}, {6, 5}, {5, 6}, {4, 7}, {5, 7}, {6, 6},
  79.   {7, 5}, {7, 6}, {6, 7}, {7, 7}
  80.   };
  81. /* Array mapping zigzag to array pointer offset. */
  82.  
  83. int zigzag_direct[64] = {
  84.   0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5, 12,
  85.   19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28, 35,
  86.   42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51,
  87. 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63};
  88. /* Set up array for fast conversion from row/column coordinates to
  89.    zig zag order.
  90. */
  91.  
  92. int scan[8][8] = {
  93.   {0, 1, 5, 6, 14, 15, 27, 28},
  94.   {2, 4, 7, 13, 16, 26, 29, 42},
  95.   {3, 8, 12, 17, 25, 30, 41, 43},
  96.   {9, 11, 18, 24, 31, 40, 44, 53},
  97.   {10, 19, 23, 32, 39, 45, 52, 54},
  98.   {20, 22, 33, 38, 46, 51, 55, 60},
  99.   {21, 34, 37, 47, 50, 56, 59, 61},
  100. {35, 36, 48, 49, 57, 58, 62, 63}};
  101. /* Initialize P and B skip flags. */
  102.  
  103. static int No_P_Flag = 0;
  104. static int No_B_Flag = 0;
  105.  
  106. /* Max lum, chrom indices for illegal block checking. */
  107.  
  108. static int lmaxx;
  109. static int lmaxy;
  110. static int cmaxx;
  111. static int cmaxy;
  112.  
  113. /*
  114.  * We use a lookup table to make sure values stay in the 0..255 range.
  115.  * Since this is cropping (ie, x = (x < 0)?0:(x>255)?255:x; ), wee call this
  116.  * table the "crop table".
  117.  * MAX_NEG_CROP is the maximum neg/pos value we can handle.
  118.  */
  119.  
  120. #define MAX_NEG_CROP 384
  121. #define NUM_CROP_ENTRIES (256+2*MAX_NEG_CROP)
  122.  
  123. #define assertCrop(x)  \
  124.    do{ \
  125.      if(!(((x) >= -MAX_NEG_CROP) && ((x) <= 256+MAX_NEG_CROP)))\
  126.      {fprintf(stderr,"Something is wrong: file %s %d\n",__FILE__, __LINE__);\
  127.        longjmp(errjmp,1); }\
  128.    } while(0)
  129.  
  130. static unsigned char cropTbl[NUM_CROP_ENTRIES];
  131.  
  132. /*
  133.   The following accounts for time and size  spent in various parsing acitivites
  134.   if ANALYSIS has been defined.
  135. */
  136.  
  137. #ifdef ANALYSIS
  138.  
  139.  
  140. unsigned int bitCount = 0;
  141.  
  142. int showmb_flag = 0;
  143. int showEachFlag = 0;
  144.  
  145. typedef struct {
  146.   int frametype;
  147.   unsigned int totsize;
  148.   unsigned int number;
  149.   unsigned int i_mbsize;
  150.   unsigned int p_mbsize;
  151.   unsigned int b_mbsize;
  152.   unsigned int bi_mbsize;
  153.   unsigned int i_mbnum;
  154.   unsigned int p_mbnum;
  155.   unsigned int b_mbnum;
  156.   unsigned int bi_mbnum;
  157.   unsigned int i_mbcbp[64];
  158.   unsigned int p_mbcbp[64];
  159.   unsigned int b_mbcbp[64];
  160.   unsigned int bi_mbcbp[64];
  161.   unsigned int i_mbcoeff[64];
  162.   unsigned int p_mbcoeff[64];
  163.   unsigned int b_mbcoeff[64];
  164.   unsigned int bi_mbcoeff[64];
  165.   double tottime;
  166. } Statval;
  167.  
  168. Statval stat_a[4];
  169. unsigned int pictureSizeCount;
  170. unsigned int mbSizeCount;
  171. unsigned int *mbCBPPtr, *mbCoeffPtr, *mbSizePtr;
  172. unsigned int cacheHit[8][8];
  173. unsigned int cacheMiss[8][8];
  174.  
  175. static void
  176. init_stat_struct(astat)
  177.   Statval *astat;
  178. {
  179.   int j;
  180.  
  181.   astat->frametype = 0;
  182.   astat->totsize = 0;
  183.   astat->number = 0;
  184.   astat->i_mbsize = 0;
  185.   astat->p_mbsize = 0;
  186.   astat->b_mbsize = 0;
  187.   astat->bi_mbsize = 0;
  188.   astat->i_mbnum = 0;
  189.   astat->p_mbnum = 0;
  190.   astat->b_mbnum = 0;
  191.   astat->bi_mbnum = 0;
  192.  
  193.   for (j = 0; j < 64; j++) {
  194.  
  195.     astat->i_mbcbp[j] = 0;
  196.     astat->p_mbcbp[j] = 0;
  197.     astat->b_mbcbp[j] = 0;
  198.     astat->bi_mbcbp[j] = 0;
  199.     astat->i_mbcoeff[j] = 0;
  200.     astat->p_mbcoeff[j] = 0;
  201.     astat->b_mbcoeff[j] = 0;
  202.     astat->bi_mbcoeff[j] = 0;
  203.   }
  204.   astat->tottime = 0.0;
  205. }
  206.  
  207. void
  208. init_stats()
  209. {
  210.   int i, j;
  211.  
  212.   for (i = 0; i < 4; i++) {
  213.     init_stat_struct(&(stat_a[i]));
  214.     stat_a[i].frametype = i;
  215.   }
  216.  
  217.   for (i = 0; i < 8; i++) {
  218.     for (j = 0; j < 8; j++) {
  219.       cacheHit[i][j] = 0;
  220.       cacheMiss[i][j] = 0;
  221.     }
  222.   }
  223.  
  224.   bitCount = 0;
  225. }
  226.  
  227. static void
  228. PrintOneStat()
  229. {
  230.   int i;
  231.  
  232.   printf("\n");
  233.   switch (stat_a[0].frametype) {
  234.   case I_TYPE:
  235.     printf("I FRAME\n");
  236.     break;
  237.   case P_TYPE:
  238.     printf("P FRAME\n");
  239.     break;
  240.   case B_TYPE:
  241.     printf("B FRAME\n");
  242.     break;
  243.   }
  244.  
  245.   printf("Size: %d bytes + %d bits\n", stat_a[0].totsize / 8, stat_a[0].totsize % 8);
  246.   if (stat_a[0].i_mbnum > 0) {
  247.     printf("\tI Macro Block Stats:\n");
  248.     printf("\t%d I Macroblocks\n", stat_a[0].i_mbnum);
  249.     printf("\tAvg. Size: %d bytes + %d bits\n",
  250.        stat_a[0].i_mbsize / (8 * stat_a[0].i_mbnum),
  251.        (stat_a[0].i_mbsize * stat_a[0].i_mbnum) % 8);
  252.     printf("\t\tCoded Block Pattern Histogram:\n");
  253.     for (i = 0; i < 64; i += 8) {
  254.       printf("\t%.6d %.6d %.6d %.6d %.6d %.6d %.6d %.6d\n", stat_a[0].i_mbcbp[i],
  255.          stat_a[0].i_mbcbp[i + 1], stat_a[0].i_mbcbp[i + 2], stat_a[0].i_mbcbp[i + 3],
  256.          stat_a[0].i_mbcbp[i + 4], stat_a[0].i_mbcbp[i + 5], stat_a[0].i_mbcbp[i + 6],
  257.          stat_a[0].i_mbcbp[i + 7]);
  258.     }
  259.     printf("\n\t\tNumber of Coefficients/Block Histogram:\n");
  260.     for (i = 0; i < 64; i += 8) {
  261.       printf("\t%.6d %.6d %.6d %.6d %.6d %.6d %.6d %.6d\n", stat_a[0].i_mbcoeff[i],
  262.          stat_a[0].i_mbcoeff[i + 1], stat_a[0].i_mbcoeff[i + 2],
  263.          stat_a[0].i_mbcoeff[i + 3], stat_a[0].i_mbcoeff[i + 4],
  264.          stat_a[0].i_mbcoeff[i + 5], stat_a[0].i_mbcoeff[i + 6],
  265.          stat_a[0].i_mbcoeff[i + 7]);
  266.     }
  267.   }
  268.   if (stat_a[0].p_mbnum > 0) {
  269.     printf("\tP Macro Block Stats:\n");
  270.     printf("\t%d P Macroblocks\n", stat_a[0].p_mbnum);
  271.     printf("\tAvg. Size: %d bytes + %d bits\n",
  272.        stat_a[0].p_mbsize / (8 * stat_a[0].p_mbnum),
  273.        (stat_a[0].p_mbsize / stat_a[0].p_mbnum) % 8);
  274.     printf("\t\tCoded Block Pattern Histogram:\n");
  275.     for (i = 0; i < 64; i += 8) {
  276.       printf("\t%.6d %.6d %.6d %.6d %.6d %.6d %.6d %.6d\n", stat_a[0].p_mbcbp[i],
  277.          stat_a[0].p_mbcbp[i + 1], stat_a[0].p_mbcbp[i + 2], stat_a[0].p_mbcbp[i + 3],
  278.          stat_a[0].p_mbcbp[i + 4], stat_a[0].p_mbcbp[i + 5], stat_a[0].p_mbcbp[i + 6],
  279.          stat_a[0].p_mbcbp[i + 7]);
  280.     }
  281.     printf("\n\t\tNumber of Coefficients/Block Histogram:\n");
  282.     for (i = 0; i < 64; i += 8) {
  283.       printf("\t%.6d %.6d %.6d %.6d %.6d %.6d %.6d %.6d\n", stat_a[0].p_mbcoeff[i],
  284.          stat_a[0].p_mbcoeff[i + 1], stat_a[0].p_mbcoeff[i + 2],
  285.          stat_a[0].p_mbcoeff[i + 3], stat_a[0].p_mbcoeff[i + 4],
  286.          stat_a[0].p_mbcoeff[i + 5], stat_a[0].p_mbcoeff[i + 6],
  287.          stat_a[0].p_mbcoeff[i + 7]);
  288.     }
  289.   }
  290.   if (stat_a[0].b_mbnum > 0) {
  291.     printf("\tB Macro Block Stats:\n");
  292.     printf("\t%d B Macroblocks\n", stat_a[0].b_mbnum);
  293.     printf("\tAvg. Size: %d bytes + %d bits\n",
  294.        stat_a[0].b_mbsize / (8 * stat_a[0].b_mbnum),
  295.        (stat_a[0].b_mbsize / stat_a[0].b_mbnum) % 8);
  296.     printf("\t\tCoded Block Pattern Histogram:\n");
  297.     for (i = 0; i < 64; i += 8) {
  298.       printf("\t%.6d %.6d %.6d %.6d %.6d %.6d %.6d %.6d\n", stat_a[0].b_mbcbp[i],
  299.          stat_a[0].b_mbcbp[i + 1], stat_a[0].b_mbcbp[i + 2], stat_a[0].b_mbcbp[i + 3],
  300.          stat_a[0].b_mbcbp[i + 4], stat_a[0].b_mbcbp[i + 5], stat_a[0].b_mbcbp[i + 6],
  301.          stat_a[0].b_mbcbp[i + 7]);
  302.     }
  303.     printf("\n\t\tNumber of Coefficients/Block Histogram:\n");
  304.     for (i = 0; i < 64; i += 8) {
  305.       printf("\t%.6d %.6d %.6d %.6d %.6d %.6d %.6d %.6d\n", stat_a[0].b_mbcoeff[i],
  306.          stat_a[0].b_mbcoeff[i + 1], stat_a[0].b_mbcoeff[i + 2],
  307.          stat_a[0].b_mbcoeff[i + 3], stat_a[0].b_mbcoeff[i + 4],
  308.          stat_a[0].b_mbcoeff[i + 5], stat_a[0].b_mbcoeff[i + 6],
  309.          stat_a[0].b_mbcoeff[i + 7]);
  310.     }
  311.   }
  312.   if (stat_a[0].bi_mbnum > 0) {
  313.     printf("\tBi Macro Block Stats:\n");
  314.     printf("\t%d Bi Macroblocks\n", stat_a[0].bi_mbnum);
  315.     printf("\tAvg. Size: %d bytes + %d bits\n",
  316.        stat_a[0].bi_mbsize / (8 * stat_a[0].bi_mbnum),
  317.        (stat_a[0].bi_mbsize * stat_a[0].bi_mbnum) % 8);
  318.     printf("\t\tCoded Block Pattern Histogram:\n");
  319.     for (i = 0; i < 64; i += 8) {
  320.       printf("\t%.6d %.6d %.6d %.6d %.6d %.6d %.6d %.6d\n", stat_a[0].bi_mbcbp[i],
  321.          stat_a[0].bi_mbcbp[i + 1], stat_a[0].bi_mbcbp[i + 2], stat_a[0].bi_mbcbp[i + 3],
  322.          stat_a[0].bi_mbcbp[i + 4], stat_a[0].bi_mbcbp[i + 5], stat_a[0].bi_mbcbp[i + 6],
  323.          stat_a[0].bi_mbcbp[i + 7]);
  324.     }
  325.     printf("\n\t\tNumber of Coefficients/Block Histogram:\n");
  326.     for (i = 0; i < 64; i += 8) {
  327.       printf("\t%.6d %.6d %.6d %.6d %.6d %.6d %.6d %.6d\n", stat_a[0].bi_mbcoeff[i],
  328.          stat_a[0].bi_mbcoeff[i + 1], stat_a[0].bi_mbcoeff[i + 2],
  329.          stat_a[0].bi_mbcoeff[i + 3], stat_a[0].bi_mbcoeff[i + 4],
  330.          stat_a[0].bi_mbcoeff[i + 5], stat_a[0].bi_mbcoeff[i + 6],
  331.          stat_a[0].bi_mbcoeff[i + 7]);
  332.     }
  333.   }
  334.   printf("\nTime to Decode: %g secs.\n", stat_a[0].tottime);
  335.   printf("****************\n");
  336. }
  337.  
  338. void
  339. PrintAllStats()
  340. {
  341.   int i, j;
  342.   unsigned int supertot, supernum;
  343.   double supertime;
  344.  
  345.   printf("\n");
  346.   printf("General Info: \n");
  347.   printf("Width: %d\nHeight: %d\n", curVidStream->mb_width * 16, curVidStream->mb_height * 16);
  348.  
  349.   for (i = 1; i < 4; i++) {
  350.  
  351.     if (stat_a[i].number == 0)
  352.       continue;
  353.  
  354.     switch (i) {
  355.     case 1:
  356.       printf("I FRAMES\n");
  357.       break;
  358.     case 2:
  359.       printf("P FRAMES\n");
  360.       break;
  361.     case 3:
  362.       printf("B FRAMES\n");
  363.       break;
  364.     }
  365.  
  366.     printf("Number: %d\n", stat_a[i].number);
  367.     printf("Avg. Size: %d bytes + %d bits\n",
  368.        stat_a[i].totsize / (8 * stat_a[i].number), (stat_a[i].totsize / stat_a[i].number) % 8);
  369.     if (stat_a[i].i_mbnum > 0) {
  370.       printf("\tI Macro Block Stats:\n");
  371.       printf("\t%d I Macroblocks\n", stat_a[i].i_mbnum);
  372.       printf("\tAvg. Size: %d bytes + %d bits\n",
  373.          stat_a[i].i_mbsize / (8 * stat_a[i].i_mbnum),
  374.          (stat_a[i].i_mbsize / stat_a[i].i_mbnum) % 8);
  375.       printf("\t\tCoded Block Pattern Histogram:\n");
  376.       for (j = 0; j < 64; j += 8) {
  377.     printf("\t%.6d %.6d %.6d %.6d %.6d %.6d %.6d %.6d\n", stat_a[i].i_mbcbp[j],
  378.            stat_a[i].i_mbcbp[j + 1], stat_a[i].i_mbcbp[j + 2], stat_a[i].i_mbcbp[j + 3],
  379.            stat_a[i].i_mbcbp[j + 4], stat_a[i].i_mbcbp[j + 5], stat_a[i].i_mbcbp[j + 6],
  380.            stat_a[i].i_mbcbp[j + 7]);
  381.       }
  382.       printf("\n\t\tNumber of Coefficients/Block Histogram:\n");
  383.       for (j = 0; j < 64; j += 8) {
  384.     printf("\t%.6d %.6d %.6d %.6d %.6d %.6d %.6d %.6d\n", stat_a[i].i_mbcoeff[j],
  385.            stat_a[i].i_mbcoeff[j + 1], stat_a[i].i_mbcoeff[j + 2],
  386.            stat_a[i].i_mbcoeff[j + 3], stat_a[i].i_mbcoeff[j + 4],
  387.            stat_a[i].i_mbcoeff[j + 5], stat_a[i].i_mbcoeff[j + 6],
  388.            stat_a[i].i_mbcoeff[j + 7]);
  389.       }
  390.     }
  391.     if (stat_a[i].p_mbnum > 0) {
  392.       printf("\tP Macro Block Stats:\n");
  393.       printf("\t%d P Macroblocks\n", stat_a[i].p_mbnum);
  394.       printf("\tAvg. Size: %d bytes + %d bits\n",
  395.          stat_a[i].p_mbsize / (8 * stat_a[i].p_mbnum),
  396.          (stat_a[i].p_mbsize / stat_a[i].p_mbnum) % 8);
  397.       printf("\t\tCoded Block Pattern Histogram:\n");
  398.       for (j = 0; j < 64; j += 8) {
  399.     printf("\t%.6d %.6d %.6d %.6d %.6d %.6d %.6d %.6d\n", stat_a[i].p_mbcbp[j],
  400.            stat_a[i].p_mbcbp[j + 1], stat_a[i].p_mbcbp[j + 2], stat_a[i].p_mbcbp[j + 3],
  401.            stat_a[i].p_mbcbp[j + 4], stat_a[i].p_mbcbp[j + 5], stat_a[i].p_mbcbp[j + 6],
  402.            stat_a[i].p_mbcbp[j + 7]);
  403.       }
  404.       printf("\n\t\tNumber of Coefficients/Block Histogram:\n");
  405.       for (j = 0; j < 64; j += 8) {
  406.     printf("\t%.6d %.6d %.6d %.6d %.6d %.6d %.6d %.6d\n", stat_a[i].p_mbcoeff[j],
  407.            stat_a[i].p_mbcoeff[j + 1], stat_a[i].p_mbcoeff[j + 2],
  408.            stat_a[i].p_mbcoeff[j + 3], stat_a[i].p_mbcoeff[j + 4],
  409.            stat_a[i].p_mbcoeff[j + 5], stat_a[i].p_mbcoeff[j + 6],
  410.            stat_a[i].p_mbcoeff[j + 7]);
  411.       }
  412.     }
  413.     if (stat_a[i].b_mbnum > 0) {
  414.       printf("\tB Macro Block Stats:\n");
  415.       printf("\t%d B Macroblocks\n", stat_a[i].b_mbnum);
  416.       printf("\tAvg. Size: %d bytes + %d bits\n",
  417.          stat_a[i].b_mbsize / (8 * stat_a[i].b_mbnum),
  418.          (stat_a[i].b_mbsize * stat_a[i].b_mbnum) % 8);
  419.       printf("\t\tCoded Block Pattern Histogram:\n");
  420.       for (j = 0; j < 64; j += 8) {
  421.     printf("\t%.6d %.6d %.6d %.6d %.6d %.6d %.6d %.6d\n", stat_a[i].b_mbcbp[j],
  422.            stat_a[i].b_mbcbp[j + 1], stat_a[i].b_mbcbp[j + 2], stat_a[i].b_mbcbp[j + 3],
  423.            stat_a[i].b_mbcbp[j + 4], stat_a[i].b_mbcbp[j + 5], stat_a[i].b_mbcbp[j + 6],
  424.            stat_a[i].b_mbcbp[j + 7]);
  425.       }
  426.       printf("\n\t\tNumber of Coefficients/Block Histogram:\n");
  427.       for (j = 0; j < 64; j += 8) {
  428.     printf("\t%.6d %.6d %.6d %.6d %.6d %.6d %.6d %.6d\n", stat_a[i].b_mbcoeff[j],
  429.            stat_a[i].b_mbcoeff[j + 1], stat_a[i].b_mbcoeff[j + 2],
  430.            stat_a[i].b_mbcoeff[j + 3], stat_a[i].b_mbcoeff[j + 4],
  431.            stat_a[i].b_mbcoeff[j + 5], stat_a[i].b_mbcoeff[j + 6],
  432.            stat_a[i].b_mbcoeff[j + 7]);
  433.       }
  434.     }
  435.     if (stat_a[i].bi_mbnum > 0) {
  436.       printf("\tBi Macro Block Stats:\n");
  437.       printf("\t%d Bi Macroblocks\n", stat_a[i].bi_mbnum);
  438.       printf("\tAvg. Size: %d bytes + %d bits\n",
  439.          stat_a[i].bi_mbsize / (8 * stat_a[i].bi_mbnum),
  440.          (stat_a[i].bi_mbsize * stat_a[i].bi_mbnum) % 8);
  441.       printf("\t\tCoded Block Pattern Histogram:\n");
  442.       for (j = 0; j < 64; j += 8) {
  443.     printf("\t%.6d %.6d %.6d %.6d %.6d %.6d %.6d %.6d\n", stat_a[i].bi_mbcbp[j],
  444.            stat_a[i].bi_mbcbp[j + 1], stat_a[i].bi_mbcbp[j + 2], stat_a[i].bi_mbcbp[j + 3],
  445.            stat_a[i].bi_mbcbp[j + 4], stat_a[i].bi_mbcbp[j + 5], stat_a[i].bi_mbcbp[j + 6],
  446.            stat_a[i].bi_mbcbp[j + 7]);
  447.       }
  448.       printf("\n\t\tNumber of Coefficients/Block Histogram:\n");
  449.       for (j = 0; j < 64; j += 8) {
  450.     printf("\t%.6d %.6d %.6d %.6d %.6d %.6d %.6d %.6d\n", stat_a[i].bi_mbcoeff[j],
  451.            stat_a[i].bi_mbcoeff[j + 1], stat_a[i].bi_mbcoeff[j + 2],
  452.            stat_a[i].bi_mbcoeff[j + 3], stat_a[i].bi_mbcoeff[j + 4],
  453.            stat_a[i].bi_mbcoeff[j + 5], stat_a[i].bi_mbcoeff[j + 6],
  454.            stat_a[i].bi_mbcoeff[j + 7]);
  455.       }
  456.     }
  457.     printf("\nAvg. Time to Decode: %f secs.\n",
  458.        (stat_a[i].tottime / ((double) stat_a[i].number)));
  459.     printf("\n");
  460.     printf("*************************\n\n");
  461.   }
  462.  
  463.   supertot = stat_a[1].totsize + stat_a[2].totsize + stat_a[3].totsize;
  464.   supernum = stat_a[1].number + stat_a[2].number + stat_a[3].number;
  465.   supertime = stat_a[1].tottime + stat_a[2].tottime + stat_a[3].tottime;
  466.  
  467.   printf("Total Number of Frames: %d\n", supernum);
  468.   printf("Avg Frame Size: %d bytes %d bits\n",
  469.      supertot / (8 * supernum), (supertot / supernum) % 8);
  470.   printf("Total Time Decoding: %g secs.\n", supertime);
  471.   printf("Avg Decoding Time/Frame: %g secs.\n", supertime / ((double) supernum));
  472.   printf("Avg Decoding Frames/Sec: %g secs.\n", ((double) supernum) / supertime);
  473.   printf("\n");
  474.  
  475.   printf("Cache Hits/Miss\n");
  476.   for (i = 0; i < 8; i++) {
  477.     printf("%.6d/%.6d\t%.6d/%.6d\t%.6d/%.6d\t%.6d/%.6d\n",
  478.        cacheHit[i][0], cacheMiss[i][0], cacheHit[i][1], cacheMiss[i][1],
  479.        cacheHit[i][2], cacheMiss[i][2], cacheHit[i][3], cacheMiss[i][3]);
  480.     printf("%.6d/%.6d\t%.6d/%.6d\t%.6d/%.6d\t%.6d/%.6d\n",
  481.        cacheHit[i][4], cacheMiss[i][4], cacheHit[i][5], cacheMiss[i][5],
  482.        cacheHit[i][6], cacheMiss[i][6], cacheHit[i][7], cacheMiss[i][7]);
  483.   }
  484.  
  485. }
  486.  
  487. static void
  488. CollectStats()
  489. {
  490.   int i, j;
  491.  
  492.   i = stat_a[0].frametype;
  493.  
  494.   stat_a[i].totsize += stat_a[0].totsize;
  495.   stat_a[i].number += stat_a[0].number;
  496.   stat_a[i].i_mbsize += stat_a[0].i_mbsize;
  497.   stat_a[i].p_mbsize += stat_a[0].p_mbsize;
  498.   stat_a[i].b_mbsize += stat_a[0].b_mbsize;
  499.   stat_a[i].bi_mbsize += stat_a[0].bi_mbsize;
  500.   stat_a[i].i_mbnum += stat_a[0].i_mbnum;
  501.   stat_a[i].p_mbnum += stat_a[0].p_mbnum;
  502.   stat_a[i].b_mbnum += stat_a[0].b_mbnum;
  503.   stat_a[i].bi_mbnum += stat_a[0].bi_mbnum;
  504.  
  505.   for (j = 0; j < 64; j++) {
  506.  
  507.     stat_a[i].i_mbcbp[j] += stat_a[0].i_mbcbp[j];
  508.     stat_a[i].p_mbcbp[j] += stat_a[0].p_mbcbp[j];
  509.     stat_a[i].b_mbcbp[j] += stat_a[0].b_mbcbp[j];
  510.     stat_a[i].bi_mbcbp[j] += stat_a[0].bi_mbcbp[j];
  511.     stat_a[i].i_mbcoeff[j] += stat_a[0].i_mbcoeff[j];
  512.     stat_a[i].p_mbcoeff[j] += stat_a[0].p_mbcoeff[j];
  513.     stat_a[i].b_mbcoeff[j] += stat_a[0].b_mbcoeff[j];
  514.     stat_a[i].bi_mbcoeff[j] += stat_a[0].bi_mbcoeff[j];
  515.   }
  516.  
  517.   stat_a[i].tottime += stat_a[0].tottime;
  518.  
  519.   init_stat_struct(&(stat_a[0]));
  520. }
  521.  
  522. static unsigned int
  523. bitCountRead()
  524. {
  525.   return bitCount;
  526. }
  527.  
  528. static void
  529. StartTime()
  530. {
  531.   stat_a[0].tottime = ReadSysClock();
  532. }
  533.  
  534. static void
  535. EndTime()
  536. {
  537.   stat_a[0].tottime = ReadSysClock() - stat_a[0].tottime;
  538. }
  539. #endif
  540.  
  541. /*
  542.  *--------------------------------------------------------------
  543.  *
  544.  * NewVidStream --
  545.  *
  546.  *    Allocates and initializes a VidStream structure. Takes
  547.  *      as parameter requested size for buffer length.
  548.  *
  549.  * Results:
  550.  *    A pointer to the new VidStream structure.
  551.  *
  552.  * Side effects:
  553.  *      None.
  554.  *
  555.  *--------------------------------------------------------------
  556.  */
  557.  
  558. VidStream *
  559. NewVidStream(bufLength)
  560.   int bufLength;
  561. {
  562.   int i, j;
  563.   VidStream *new;
  564.   static unsigned char default_intra_matrix[64] = {
  565.     8, 16, 19, 22, 26, 27, 29, 34,
  566.     16, 16, 22, 24, 27, 29, 34, 37,
  567.     19, 22, 26, 27, 29, 34, 34, 38,
  568.     22, 22, 26, 27, 29, 34, 37, 40,
  569.     22, 26, 27, 29, 32, 35, 40, 48,
  570.     26, 27, 29, 32, 35, 40, 48, 58,
  571.     26, 27, 29, 34, 38, 46, 56, 69,
  572.   27, 29, 35, 38, 46, 56, 69, 83};
  573.  
  574.   /* Check for legal buffer length. */
  575.  
  576.   if (bufLength < 4)
  577.     return NULL;
  578.  
  579.   /* Make buffer length multiple of 4. */
  580.  
  581.   bufLength = (bufLength + 3) >> 2;
  582.  
  583.   /* Allocate memory for new structure. */
  584.  
  585.   new = (VidStream *) malloc(sizeof(VidStream));
  586.  
  587.   /* Initialize pointers to extension and user data. */
  588.  
  589.   new->group.ext_data = new->group.user_data =
  590.     new->picture.extra_info = new->picture.user_data =
  591.     new->picture.ext_data = new->slice.extra_info =
  592.     new->ext_data = new->user_data = NULL;
  593.  
  594.   /* Copy default intra matrix. */
  595.  
  596.   for (i = 0; i < 8; i++) {
  597.     for (j = 0; j < 8; j++) {
  598.       new->intra_quant_matrix[j][i] = default_intra_matrix[i * 8 + j];
  599.     }
  600.   }
  601.  
  602.   /* Initialize crop table. */
  603.  
  604.   for (i = (-MAX_NEG_CROP); i < NUM_CROP_ENTRIES - MAX_NEG_CROP; i++) {
  605.     if (i <= 0) {
  606.       cropTbl[i + MAX_NEG_CROP] = 0;
  607.     } else if (i >= 255) {
  608.       cropTbl[i + MAX_NEG_CROP] = 255;
  609.     } else {
  610.       cropTbl[i + MAX_NEG_CROP] = i;
  611.     }
  612.   }
  613.  
  614.   /* Initialize non intra quantization matrix. */
  615.  
  616.   for (i = 0; i < 8; i++) {
  617.     for (j = 0; j < 8; j++) {
  618.       new->non_intra_quant_matrix[j][i] = 16;
  619.     }
  620.   }
  621.  
  622.   /* Initialize pointers to image spaces. */
  623.  
  624.   new->current = new->past = new->future = NULL;
  625.   for (i = 0; i < RING_BUF_SIZE; i++) {
  626.     new->ring[i] = NULL;
  627.   }
  628.  
  629.   /* Create buffer. */
  630.  
  631.   new->buf_start = (unsigned int *) malloc(bufLength * 4);
  632.  
  633.   /*
  634.    * Set max_buf_length to one less than actual length to deal with messy
  635.    * data without proper seq. end codes.
  636.    */
  637.  
  638.   new->max_buf_length = bufLength - 1;
  639.  
  640.   /* Initialize bitstream i/o fields. */
  641.  
  642.   new->bit_offset = 0;
  643.   new->buf_length = 0;
  644.   new->buffer = new->buf_start;
  645.  
  646.  
  647.   /* Return structure. */
  648.  
  649.   return new;
  650. }
  651.  
  652.  
  653.  
  654. /*
  655.  *--------------------------------------------------------------
  656.  *
  657.  * DestroyVidStream --
  658.  *
  659.  *    Deallocates a VidStream structure.
  660.  *
  661.  * Results:
  662.  *      None.
  663.  *
  664.  * Side effects:
  665.  *    None.
  666.  *
  667.  *--------------------------------------------------------------
  668.  */
  669. void
  670. DestroyVidStream(astream)
  671.   VidStream *astream;
  672. {
  673.   int i;
  674.  
  675.   if(!astream)
  676.     return ;
  677.  
  678.   if (astream->ext_data != NULL)
  679.   {
  680.     free(astream->ext_data);
  681.     astream->ext_data = 0;
  682.   }
  683.  
  684.   if (astream->user_data != NULL)
  685.   {
  686.     free(astream->user_data);
  687.     astream->user_data = 0;
  688.   }
  689.  
  690.   if (astream->group.ext_data != NULL)
  691.   {
  692.     free(astream->group.ext_data);
  693.     astream->group.ext_data = 0;
  694.   }
  695.  
  696.   if (astream->group.user_data != NULL)
  697.   {
  698.     free(astream->group.user_data);
  699.     astream->group.user_data = 0;
  700.   }
  701.  
  702.   if (astream->picture.extra_info != NULL)
  703.   {
  704.     free(astream->picture.extra_info);
  705.     astream->picture.extra_info = 0;
  706.   }
  707.  
  708.   if (astream->picture.ext_data != NULL)
  709.   {
  710.    free(astream->picture.ext_data);
  711.    astream->picture.ext_data = 0;
  712.   }
  713.  
  714.  
  715.   if (astream->picture.user_data != NULL)
  716.   {
  717.     free(astream->picture.user_data);
  718.     astream->picture.user_data = 0;
  719.   }
  720.  
  721.   if (astream->slice.extra_info != NULL)
  722.   {
  723.     free(astream->slice.extra_info);
  724.     astream->slice.extra_info = 0;
  725.   }
  726.  
  727.   if (astream->buf_start != NULL)
  728.   {
  729.     free(astream->buf_start);
  730.     astream->buf_start = 0;
  731.   }
  732.  
  733.   for (i = 0; i < RING_BUF_SIZE; i++) {
  734.     if (astream->ring[i] != NULL) {
  735.       DestroyPictImage(astream->ring[i]);
  736.       astream->ring[i] = NULL;
  737.     }
  738.   }
  739.  
  740.   free((char *) astream);
  741. }
  742.  
  743.  
  744.  
  745.  
  746. /*
  747.  *--------------------------------------------------------------
  748.  *
  749.  * NewPictImage --
  750.  *
  751.  *    Allocates and initializes a PictImage structure.
  752.  *      The width and height of the image space are passed in
  753.  *      as parameters.
  754.  *
  755.  * Results:
  756.  *    A pointer to the new PictImage structure.
  757.  *
  758.  * Side effects:
  759.  *    None.
  760.  *
  761.  *--------------------------------------------------------------
  762.  */
  763.  
  764. PictImage *
  765. NewPictImage(width, height)
  766.   unsigned int width, height;
  767. {
  768.   PictImage *new;
  769.  
  770.   /* Allocate memory space for new structure. */
  771.  
  772.   new = (PictImage *) malloc(sizeof(PictImage));
  773.  
  774.  
  775.   /* Allocate memory for image spaces. */
  776.  
  777.   {
  778.  
  779.     if ((ditherType == Twox2_DITHER) || (ditherType == FULL_COLOR_DITHER)) {
  780.       new->display = (unsigned char *) malloc(width * height * 4);
  781.     } else {
  782.       new->display = (unsigned char *) malloc(width * height);
  783.     }
  784.   }
  785.  
  786.   new->luminance = (unsigned char *) malloc(width * height);
  787.   new->Cr = (unsigned char *) malloc(width * height / 4);
  788.   new->Cb = (unsigned char *) malloc(width * height / 4);
  789.  
  790.   /* Reset locked flag. */
  791.  
  792.   new->locked = 0;
  793.  
  794.   /* Return pointer to new structure. */
  795.  
  796.   return new;
  797. }
  798.  
  799.  
  800.  
  801. /*
  802.  *--------------------------------------------------------------
  803.  *
  804.  * DestroyPictImage --
  805.  *
  806.  *    Deallocates a PictImage structure.
  807.  *
  808.  * Results:
  809.  *      None.
  810.  *
  811.  * Side effects:
  812.  *    None.
  813.  *
  814.  *--------------------------------------------------------------
  815.  */
  816. void
  817. DestroyPictImage(apictimage)
  818.   PictImage *apictimage;
  819. {
  820.   if (apictimage->luminance != NULL) {
  821.     free(apictimage->luminance);
  822.   }
  823.   if (apictimage->Cr != NULL) {
  824.     free(apictimage->Cr);
  825.   }
  826.   if (apictimage->Cb != NULL) {
  827.     free(apictimage->Cb);
  828.   }
  829.  
  830.   if (apictimage->display != NULL) {
  831.     free(apictimage->display);
  832.   }
  833.   free(apictimage);
  834. }
  835.  
  836.  
  837.  
  838. /*
  839.  *--------------------------------------------------------------
  840.  *
  841.  * mpegVidRsrc --
  842.  *
  843.  *      Parses bit stream until MB_QUANTUM number of
  844.  *      macroblocks have been decoded or current slice or
  845.  *      picture ends, whichever comes first. If the start
  846.  *      of a frame is encountered, the frame is time stamped
  847.  *      with the value passed in time_stamp. If the value
  848.  *      passed in buffer is not null, the video stream buffer
  849.  *      is set to buffer and the length of the buffer is
  850.  *      expected in value passed in through length. The current
  851.  *      video stream is set to vid_stream. If vid_stream
  852.  *      is passed as NULL, a new VidStream structure is created
  853.  *      and initialized and used as the current video stream.
  854.  *
  855.  * Results:
  856.  *      A pointer to the video stream structure used.
  857.  *
  858.  * Side effects:
  859.  *      Bit stream is irreversibly parsed. If a picture is completed,
  860.  *      a function is called to display the frame at the correct time.
  861.  *
  862.  *--------------------------------------------------------------
  863.  */
  864.  
  865. static int first_entry = 1;
  866. static int last_frame;
  867.  
  868. void
  869. reset_mpeg_stream(void)
  870. {
  871.    first_entry = 1;
  872.    last_frame = 0;
  873. }
  874.  
  875. VidStream *
  876. mpegVidRsrc(time_stamp, vid_stream)
  877.   TimeStamp time_stamp;
  878.   VidStream *vid_stream;
  879. {
  880.   unsigned int data;
  881.   int i, status;
  882.   int newframe = 0;
  883.  
  884.   /* if last frame is read, return 0 */
  885.  
  886.   if(last_frame)
  887.   {
  888.      DestroyVidStream(curVidStream);
  889.      curVidStream = 0;
  890.      return 0;
  891.    }
  892.  
  893.   /* If vid_stream is null, create new VidStream structure. */
  894.   do {
  895.  
  896.   if (vid_stream == NULL) {
  897.     return NULL;
  898.   }
  899.   /*
  900.    * Set global curVidStream to vid_stream. Necessary because bit i/o use
  901.    * curVidStream and are not passed vid_stream. Also set global bitstream
  902.    * parameters.
  903.    */
  904.  
  905.   curVidStream = vid_stream;
  906.   bitOffset = curVidStream->bit_offset;
  907. #ifdef UTIL2
  908.   curBits = *curVidStream->buffer << bitOffset;
  909. #else
  910.   curBits = *curVidStream->buffer;
  911. #endif
  912.   bufLength = curVidStream->buf_length;
  913.   bitBuffer = curVidStream->buffer;
  914.  
  915.   /*
  916.    * If called for the first time, find start code, make sure it is a
  917.    * sequence start code.
  918.    */
  919.  
  920.   if (first_entry) {
  921.     next_start_code();
  922.     show_bits32(data);
  923.     if (data != SEQ_START_CODE) {
  924.       fprintf(stderr, "This is not an MPEG stream.\n");
  925.       DestroyVidStream(curVidStream);
  926.       curVidStream = 0;
  927.       return 0;
  928.     }
  929.     first_entry = 0;
  930.   }
  931.   /* Get next 32 bits (size of start codes). */
  932.  
  933.   show_bits32(data);
  934.  
  935.   /*
  936.    * Process according to start code (or parse macroblock if not a start code
  937.    * at all.
  938.    */
  939.  
  940.   switch (data) {
  941.  
  942.   case SEQ_END_CODE:
  943.  
  944.     /* Display last frame. */
  945.  
  946.     if (vid_stream->future != NULL) {
  947.       vid_stream->current = vid_stream->future;
  948.       newframe = 1;
  949.       last_frame = 1;
  950.       return vid_stream;
  951.     }
  952.     
  953.     return 0;
  954.     break;
  955.  
  956.   case SEQ_START_CODE:
  957.  
  958.     /* Sequence start code. Parse sequence header. */
  959.  
  960.     if (ParseSeqHead(vid_stream) != PARSE_OK)
  961.       goto error;
  962.  
  963.     /*
  964.      * Return after sequence start code so that application above can use
  965.      * info in header.
  966.      */
  967.  
  968.     goto done;
  969.  
  970.   case GOP_START_CODE:
  971.  
  972.     /* Group of Pictures start code. Parse gop header. */
  973.  
  974.     if (ParseGOP(vid_stream) != PARSE_OK)
  975.       goto error;
  976.  
  977.  
  978.   case PICTURE_START_CODE:
  979.  
  980.     /* Picture start code. Parse picture header and first slice header. */
  981.  
  982.     status = ParsePicture(vid_stream, time_stamp);
  983.  
  984.     if (status == SKIP_PICTURE) {
  985.       next_start_code();
  986.       fprintf(stderr, "Skipping picture...");
  987.       while (!next_bits(32, PICTURE_START_CODE)) {
  988.     if (next_bits(32, GOP_START_CODE))
  989.       break;
  990.     else if (next_bits(32, SEQ_END_CODE))
  991.       break;
  992.     flush_bits(24);
  993.     next_start_code();
  994.       }
  995.       fprintf(stderr, "Done.\n");
  996.       goto done;
  997.     } else if (status != PARSE_OK)
  998.       goto error;
  999.  
  1000.  
  1001.     if (ParseSlice(vid_stream) != PARSE_OK)
  1002.       goto error;
  1003.     break;
  1004.  
  1005.   default:
  1006.  
  1007.     /* Check for slice start code. */
  1008.  
  1009.     if ((data >= SLICE_MIN_START_CODE) && (data <= SLICE_MAX_START_CODE)) {
  1010.  
  1011.       /* Slice start code. Parse slice header. */
  1012.  
  1013.       if (ParseSlice(vid_stream) != PARSE_OK)
  1014.     goto error;
  1015.     }
  1016.     break;
  1017.   }
  1018.  
  1019.   /* Parse next MB_QUANTUM macroblocks. */
  1020.  
  1021.   for (i = 0; i < MB_QUANTUM; i++) {
  1022.  
  1023.     /* Check to see if actually a startcode and not a macroblock. */
  1024.  
  1025.     if (!next_bits(23, 0x00000000)) {
  1026.  
  1027.       /* Not start code. Parse Macroblock. */
  1028.  
  1029.       if (ParseMacroBlock(vid_stream) != PARSE_OK)
  1030.     goto error;
  1031.  
  1032.  
  1033.     } else {
  1034.  
  1035.       /* Not macroblock, actually start code. Get start code. */
  1036.  
  1037.       next_start_code();
  1038.       show_bits32(data);
  1039.  
  1040.       /*
  1041.        * If start code is outside range of slice start codes, frame is
  1042.        * complete, display frame.
  1043.        */
  1044.  
  1045.       if ((data < SLICE_MIN_START_CODE) || (data > SLICE_MAX_START_CODE)) {
  1046.  
  1047. #ifdef ANALYSIS
  1048.     EndTime();
  1049.     stat_a[0].totsize += bitCountRead() - pictureSizeCount;
  1050.     if (showEachFlag) {
  1051.       PrintOneStat();
  1052.     };
  1053.  
  1054.     CollectStats();
  1055. #endif
  1056.     newframe = DoPictureDisplay(vid_stream);
  1057.       }
  1058.       break;
  1059.     }
  1060.   }
  1061.  
  1062.   /* Return pointer to video stream structure. */
  1063.  
  1064.   goto done;
  1065.  
  1066. error:
  1067. #if 0
  1068.   fprintf(stderr, "Error!!!!\n");
  1069. #endif
  1070.   next_start_code();
  1071.   goto done;
  1072.  
  1073. done:
  1074.  
  1075.   /* Copy global bit i/o variables back into vid_stream. */
  1076.  
  1077.   vid_stream->buffer = bitBuffer;
  1078.   vid_stream->buf_length = bufLength;
  1079.   vid_stream->bit_offset = bitOffset;
  1080.  
  1081.   } while (!newframe);
  1082.   return vid_stream;
  1083. }
  1084.  
  1085.  
  1086.  
  1087. /*
  1088.  *--------------------------------------------------------------
  1089.  *
  1090.  * ParseSeqHead --
  1091.  *
  1092.  *      Assumes bit stream is at the begining of the sequence
  1093.  *      header start code. Parses off the sequence header.
  1094.  *
  1095.  * Results:
  1096.  *      Fills the vid_stream structure with values derived and
  1097.  *      decoded from the sequence header. Allocates the pict image
  1098.  *      structures based on the dimensions of the image space
  1099.  *      found in the sequence header.
  1100.  *
  1101.  * Side effects:
  1102.  *      Bit stream irreversibly parsed off.
  1103.  *
  1104.  *--------------------------------------------------------------
  1105.  */
  1106.  
  1107. static int
  1108. ParseSeqHead(vid_stream)
  1109.   VidStream *vid_stream;
  1110. {
  1111.  
  1112.   unsigned int data;
  1113.   int i;
  1114.  
  1115.   /* Flush off sequence start code. */
  1116.  
  1117.   flush_bits32;
  1118.  
  1119.   /* Get horizontal size of image space. */
  1120.  
  1121.   get_bits12(data);
  1122.   vid_stream->h_size = data;
  1123.  
  1124.   /* Get vertical size of image space. */
  1125.  
  1126.   get_bits12(data);
  1127.   vid_stream->v_size = data;
  1128.  
  1129.   /* Calculate macroblock width and height of image space. */
  1130.  
  1131.   vid_stream->mb_width = (vid_stream->h_size + 15) / 16;
  1132.   vid_stream->mb_height = (vid_stream->v_size + 15) / 16;
  1133.  
  1134.   /* If dither type is MBORDERED allocate ditherFlags. */
  1135.  
  1136.   if (ditherType == MBORDERED_DITHER) {
  1137.     ditherFlags = (char *) malloc(vid_stream->mb_width*vid_stream->mb_height);
  1138.   }
  1139.  
  1140.   /* Initialize lmaxx, lmaxy, cmaxx, cmaxy. */
  1141.  
  1142.   lmaxx = vid_stream->mb_width*16-1;
  1143.   lmaxy = vid_stream->mb_height*16-1;
  1144.   cmaxx = vid_stream->mb_width*8-1;
  1145.   cmaxy = vid_stream->mb_height*8-1;
  1146.  
  1147.   /*
  1148.    * Initialize ring buffer of pict images now that dimensions of image space
  1149.    * are known.
  1150.    */
  1151.  
  1152.  
  1153.   if (vid_stream->ring[0] == NULL) {
  1154.     for (i = 0; i < RING_BUF_SIZE; i++) {
  1155.       vid_stream->ring[i] = NewPictImage(vid_stream->mb_width * 16,
  1156.                      vid_stream->mb_height * 16);
  1157.     }
  1158.   }
  1159.  
  1160.   /* Parse of aspect ratio code. */
  1161.  
  1162.   get_bits4(data);
  1163.   vid_stream->aspect_ratio = (unsigned char) data;
  1164.  
  1165.   /* Parse off picture rate code. */
  1166.  
  1167.   get_bits4(data);
  1168.   vid_stream->picture_rate = (unsigned char) data;
  1169.  
  1170.   /* Parse off bit rate. */
  1171.  
  1172.   get_bits18(data);
  1173.   vid_stream->bit_rate = data;
  1174.  
  1175.   /* Flush marker bit. */
  1176.  
  1177.   flush_bits(1);
  1178.  
  1179.   /* Parse off vbv buffer size. */
  1180.  
  1181.   get_bits10(data);
  1182.   vid_stream->vbv_buffer_size = data;
  1183.  
  1184.   /* Parse off contrained parameter flag. */
  1185.  
  1186.   get_bits1(data);
  1187.   if (data) {
  1188.     vid_stream->const_param_flag = TRUE;
  1189.   } else
  1190.     vid_stream->const_param_flag = FALSE;
  1191.  
  1192.   /*
  1193.    * If intra_quant_matrix_flag set, parse off intra quant matrix values.
  1194.    */
  1195.  
  1196.   get_bits1(data);
  1197.   if (data) {
  1198.     for (i = 0; i < 64; i++) {
  1199.       get_bits8(data);
  1200.  
  1201.       vid_stream->intra_quant_matrix[zigzag[i][1]][zigzag[i][0]] =
  1202.     (unsigned char) data;
  1203.     }
  1204.   }
  1205.   /*
  1206.    * If non intra quant matrix flag set, parse off non intra quant matrix
  1207.    * values.
  1208.    */
  1209.  
  1210.   get_bits1(data);
  1211.   if (data) {
  1212.     for (i = 0; i < 64; i++) {
  1213.       get_bits8(data);
  1214.  
  1215.       vid_stream->non_intra_quant_matrix[zigzag[i][1]][zigzag[i][0]] =
  1216.     (unsigned char) data;
  1217.     }
  1218.   }
  1219.   /* Go to next start code. */
  1220.  
  1221.   next_start_code();
  1222.  
  1223.   /*
  1224.    * If next start code is extension start code, parse off extension data.
  1225.    */
  1226.  
  1227.   if (next_bits(32, EXT_START_CODE)) {
  1228.     flush_bits32;
  1229.     if (vid_stream->ext_data != NULL) {
  1230.       free(vid_stream->ext_data);
  1231.       vid_stream->ext_data = NULL;
  1232.     }
  1233.     vid_stream->ext_data = get_ext_data();
  1234.   }
  1235.   /* If next start code is user start code, parse off user data. */
  1236.  
  1237.   if (next_bits(32, USER_START_CODE)) {
  1238.     flush_bits32;
  1239.     if (vid_stream->user_data != NULL) {
  1240.       free(vid_stream->user_data);
  1241.       vid_stream->user_data = NULL;
  1242.     }
  1243.     vid_stream->user_data = get_ext_data();
  1244.   }
  1245.   return PARSE_OK;
  1246. }
  1247.  
  1248.  
  1249.  
  1250. /*
  1251.  *--------------------------------------------------------------
  1252.  *
  1253.  * ParseGOP --
  1254.  *
  1255.  *      Parses of group of pictures header from bit stream
  1256.  *      associated with vid_stream.
  1257.  *
  1258.  * Results:
  1259.  *      Values in gop header placed into video stream structure.
  1260.  *
  1261.  * Side effects:
  1262.  *      Bit stream irreversibly parsed.
  1263.  *
  1264.  *--------------------------------------------------------------
  1265.  */
  1266.  
  1267. static int
  1268. ParseGOP(vid_stream)
  1269.   VidStream *vid_stream;
  1270. {
  1271.   unsigned int data;
  1272.  
  1273.   /* Flush group of pictures start code. WWWWWWOOOOOOOSSSSSSHHHHH!!! */
  1274.  
  1275.   flush_bits32;
  1276.  
  1277.   /* Parse off drop frame flag. */
  1278.  
  1279.   get_bits1(data);
  1280.   if (data) {
  1281.     vid_stream->group.drop_flag = TRUE;
  1282.   } else
  1283.     vid_stream->group.drop_flag = FALSE;
  1284.  
  1285.   /* Parse off hour component of time code. */
  1286.  
  1287.   get_bits5(data);
  1288.   vid_stream->group.tc_hours = data;
  1289.  
  1290.   /* Parse off minute component of time code. */
  1291.  
  1292.   get_bits6(data);
  1293.   vid_stream->group.tc_minutes = data;
  1294.  
  1295.   /* Flush marker bit. */
  1296.  
  1297.   flush_bits(1);
  1298.  
  1299.   /* Parse off second component of time code. */
  1300.  
  1301.   get_bits6(data);
  1302.   vid_stream->group.tc_seconds = data;
  1303.  
  1304.   /* Parse off picture count component of time code. */
  1305.  
  1306.   get_bits6(data);
  1307.   vid_stream->group.tc_pictures = data;
  1308.  
  1309.   /* Parse off closed gop and broken link flags. */
  1310.  
  1311.   get_bits2(data);
  1312.   if (data > 1) {
  1313.     vid_stream->group.closed_gop = TRUE;
  1314.     if (data > 2) {
  1315.       vid_stream->group.broken_link = TRUE;
  1316.     } else
  1317.       vid_stream->group.broken_link = FALSE;
  1318.   } else {
  1319.     vid_stream->group.closed_gop = FALSE;
  1320.     if (data) {
  1321.       vid_stream->group.broken_link = TRUE;
  1322.     } else
  1323.       vid_stream->group.broken_link = FALSE;
  1324.   }
  1325.  
  1326.   /* Goto next start code. */
  1327.  
  1328.   next_start_code();
  1329.  
  1330.   /* If next start code is extension data, parse off extension data. */
  1331.  
  1332.   if (next_bits(32, EXT_START_CODE)) {
  1333.     flush_bits32;
  1334.     if (vid_stream->group.ext_data != NULL) {
  1335.       free(vid_stream->group.ext_data);
  1336.       vid_stream->group.ext_data = NULL;
  1337.     }
  1338.     vid_stream->group.ext_data = get_ext_data();
  1339.   }
  1340.   /* If next start code is user data, parse off user data. */
  1341.  
  1342.   if (next_bits(32, USER_START_CODE)) {
  1343.     flush_bits32;
  1344.     if (vid_stream->group.user_data != NULL) {
  1345.       free(vid_stream->group.user_data);
  1346.       vid_stream->group.user_data = NULL;
  1347.     }
  1348.     vid_stream->group.user_data = get_ext_data();
  1349.   }
  1350.   return PARSE_OK;
  1351. }
  1352.  
  1353.  
  1354.  
  1355. /*
  1356.  *--------------------------------------------------------------
  1357.  *
  1358.  * ParsePicture --
  1359.  *
  1360.  *      Parses picture header. Marks picture to be presented
  1361.  *      at particular time given a time stamp.
  1362.  *
  1363.  * Results:
  1364.  *      Values from picture header put into video stream structure.
  1365.  *
  1366.  * Side effects:
  1367.  *      Bit stream irreversibly parsed.
  1368.  *
  1369.  *--------------------------------------------------------------
  1370.  */
  1371.  
  1372. static int
  1373. ParsePicture(vid_stream, time_stamp)
  1374.   VidStream *vid_stream;
  1375.   TimeStamp time_stamp;
  1376. {
  1377.   unsigned int data;
  1378.   int i;
  1379.  
  1380.   /* Flush header start code. */
  1381.   flush_bits32;
  1382.  
  1383.   /* Parse off temporal reference. */
  1384.   get_bits10(data);
  1385.   vid_stream->picture.temp_ref = data;
  1386.  
  1387.   /* Parse of picture type. */
  1388.   get_bits3(data);
  1389.   vid_stream->picture.code_type = data;
  1390.  
  1391.   if ((vid_stream->picture.code_type == B_TYPE) &&
  1392.       (No_B_Flag ||
  1393.        (vid_stream->past == NULL) ||
  1394.        (vid_stream->future == NULL)))
  1395.     return SKIP_PICTURE;
  1396.  
  1397.   if ((vid_stream->picture.code_type == P_TYPE) &&
  1398.       (No_P_Flag || (vid_stream->future == NULL)))
  1399.     return SKIP_PICTURE;
  1400.  
  1401. #ifdef ANALYSIS
  1402.   StartTime();
  1403.   stat_a[0].frametype = vid_stream->picture.code_type;
  1404.   stat_a[0].number = 1;
  1405.   stat_a[0].totsize = 45;
  1406.   pictureSizeCount = bitCountRead();
  1407. #endif
  1408.  
  1409.   /* Parse off vbv buffer delay value. */
  1410.   get_bits16(data);
  1411.   vid_stream->picture.vbv_delay = data;
  1412.  
  1413.   /* If P or B type frame... */
  1414.  
  1415.   if ((vid_stream->picture.code_type == 2) || (vid_stream->picture.code_type == 3)) {
  1416.  
  1417.     /* Parse off forward vector full pixel flag. */
  1418.     get_bits1(data);
  1419.     if (data)
  1420.       vid_stream->picture.full_pel_forw_vector = TRUE;
  1421.     else
  1422.       vid_stream->picture.full_pel_forw_vector = FALSE;
  1423.  
  1424.     /* Parse of forw_r_code. */
  1425.     get_bits3(data);
  1426.  
  1427.     /* Decode forw_r_code into forw_r_size and forw_f. */
  1428.  
  1429.     vid_stream->picture.forw_r_size = data - 1;
  1430.     vid_stream->picture.forw_f = (1 << vid_stream->picture.forw_r_size);
  1431.   }
  1432.   /* If B type frame... */
  1433.  
  1434.   if (vid_stream->picture.code_type == 3) {
  1435.  
  1436.     /* Parse off back vector full pixel flag. */
  1437.     get_bits1(data);
  1438.     if (data)
  1439.       vid_stream->picture.full_pel_back_vector = TRUE;
  1440.     else
  1441.       vid_stream->picture.full_pel_back_vector = FALSE;
  1442.  
  1443.     /* Parse off back_r_code. */
  1444.     get_bits3(data);
  1445.  
  1446.     /* Decode back_r_code into back_r_size and back_f. */
  1447.  
  1448.     vid_stream->picture.back_r_size = data - 1;
  1449.     vid_stream->picture.back_f = (1 << vid_stream->picture.back_r_size);
  1450.   }
  1451.   /* Get extra bit picture info. */
  1452.  
  1453.   if (vid_stream->picture.extra_info != NULL) {
  1454.     free(vid_stream->picture.extra_info);
  1455.     vid_stream->picture.extra_info = NULL;
  1456.   }
  1457.   vid_stream->picture.extra_info = get_extra_bit_info();
  1458.  
  1459.   /* Goto next start code. */
  1460.   next_start_code();
  1461.  
  1462.   /* If start code is extension start code, parse off extension data. */
  1463.  
  1464.   if (next_bits(32, EXT_START_CODE)) {
  1465.     flush_bits32;
  1466.  
  1467.     if (vid_stream->picture.ext_data != NULL) {
  1468.       free(vid_stream->picture.ext_data);
  1469.       vid_stream->picture.ext_data = NULL;
  1470.     }
  1471.     vid_stream->picture.ext_data = get_ext_data();
  1472.   }
  1473.   /* If start code is user start code, parse off user data. */
  1474.  
  1475.   if (next_bits(32, USER_START_CODE)) {
  1476.     flush_bits32;
  1477.  
  1478.     if (vid_stream->picture.user_data != NULL) {
  1479.       free(vid_stream->picture.user_data);
  1480.       vid_stream->picture.user_data = NULL;
  1481.     }
  1482.     vid_stream->picture.user_data = get_ext_data();
  1483.   }
  1484.   /* Find a pict image structure in ring buffer not currently locked. */
  1485.  
  1486.   i = 0;
  1487.  
  1488.   while (vid_stream->ring[i]->locked != 0) {
  1489.     if (++i >= RING_BUF_SIZE) {
  1490.       perror("Fatal error. Ring buffer full.");
  1491.       longjmp(errjmp,1);
  1492.     }
  1493.   }
  1494.  
  1495.   /* Set current pict image structure to the one just found in ring. */
  1496.  
  1497.   vid_stream->current = vid_stream->ring[i];
  1498.  
  1499.   /* Set time stamp. */
  1500.  
  1501.   vid_stream->current->show_time = time_stamp;
  1502.  
  1503.   /* Reset past macroblock address field. */
  1504.  
  1505.   vid_stream->mblock.past_mb_addr = -1;
  1506.  
  1507.   return PARSE_OK;
  1508. }
  1509.  
  1510.  
  1511.  
  1512. /*
  1513.  *--------------------------------------------------------------
  1514.  *
  1515.  * ParseSlice --
  1516.  *
  1517.  *      Parses off slice header.
  1518.  *
  1519.  * Results:
  1520.  *      Values found in slice header put into video stream structure.
  1521.  *
  1522.  * Side effects:
  1523.  *      Bit stream irreversibly parsed.
  1524.  *
  1525.  *--------------------------------------------------------------
  1526.  */
  1527.  
  1528. static int
  1529. ParseSlice(vid_stream)
  1530.   VidStream *vid_stream;
  1531. {
  1532.   unsigned int data;
  1533.  
  1534.   /* Flush slice start code. */
  1535.  
  1536.   flush_bits(24);
  1537.  
  1538.   /* Parse off slice vertical position. */
  1539.  
  1540.   get_bits8(data);
  1541.   vid_stream->slice.vert_pos = data;
  1542.  
  1543.   /* Parse off quantization scale. */
  1544.  
  1545.   get_bits5(data);
  1546.   vid_stream->slice.quant_scale = data;
  1547.  
  1548.   /* Parse off extra bit slice info. */
  1549.  
  1550.   if (vid_stream->slice.extra_info != NULL) {
  1551.     free(vid_stream->slice.extra_info);
  1552.     vid_stream->slice.extra_info = NULL;
  1553.   }
  1554.   vid_stream->slice.extra_info = get_extra_bit_info();
  1555.  
  1556.   /* Reset past intrablock address. */
  1557.  
  1558.   vid_stream->mblock.past_intra_addr = -2;
  1559.  
  1560.   /* Reset previous recon motion vectors. */
  1561.  
  1562.   vid_stream->mblock.recon_right_for_prev = 0;
  1563.   vid_stream->mblock.recon_down_for_prev = 0;
  1564.   vid_stream->mblock.recon_right_back_prev = 0;
  1565.   vid_stream->mblock.recon_down_back_prev = 0;
  1566.  
  1567.   /* Reset macroblock address. */
  1568.  
  1569.   vid_stream->mblock.mb_address = ((vid_stream->slice.vert_pos - 1) *
  1570.                    vid_stream->mb_width) - 1;
  1571.  
  1572.   /* Reset past dct dc y, cr, and cb values. */
  1573.  
  1574.   vid_stream->block.dct_dc_y_past = 1024;
  1575.   vid_stream->block.dct_dc_cr_past = 1024;
  1576.   vid_stream->block.dct_dc_cb_past = 1024;
  1577.  
  1578.   return PARSE_OK;
  1579. }
  1580.  
  1581.  
  1582.  
  1583. /*
  1584.  *--------------------------------------------------------------
  1585.  *
  1586.  * ParseMacroBlock --
  1587.  *
  1588.  *      Parseoff macroblock. Reconstructs DCT values. Applies
  1589.  *      inverse DCT, reconstructs motion vectors, calculates and
  1590.  *      set pixel values for macroblock in current pict image
  1591.  *      structure.
  1592.  *
  1593.  * Results:
  1594.  *      Here's where everything really happens. Welcome to the
  1595.  *      heart of darkness.
  1596.  *
  1597.  * Side effects:
  1598.  *      Bit stream irreversibly parsed off.
  1599.  *
  1600.  *--------------------------------------------------------------
  1601.  */
  1602.  
  1603. static int
  1604. ParseMacroBlock(vid_stream)
  1605.   VidStream *vid_stream;
  1606. {
  1607.   int addr_incr;
  1608.   unsigned int data;
  1609.   int mask, i, recon_right_for, recon_down_for, recon_right_back,
  1610.       recon_down_back;
  1611.   int zero_block_flag;
  1612.   BOOLEAN mb_quant, mb_motion_forw, mb_motion_back, mb_pattern;
  1613.   int no_dith_flag = 0;
  1614.  
  1615. #ifdef ANALYSIS
  1616.   mbSizeCount = bitCountRead();
  1617. #endif
  1618.  
  1619.   /*
  1620.    * Parse off macroblock address increment and add to macroblock address.
  1621.    */
  1622.   do {
  1623.     DecodeMBAddrInc(addr_incr);
  1624.     if (addr_incr == MB_ESCAPE) {
  1625.       vid_stream->mblock.mb_address += 33;
  1626.       addr_incr = MB_STUFFING;
  1627.     }
  1628.   } while (addr_incr == MB_STUFFING);
  1629.   vid_stream->mblock.mb_address += addr_incr;
  1630.  
  1631.   if (vid_stream->mblock.mb_address > (vid_stream->mb_height *
  1632.                        vid_stream->mb_width - 1))
  1633.     return SKIP_TO_START_CODE;
  1634.  
  1635.   /*
  1636.    * If macroblocks have been skipped, process skipped macroblocks.
  1637.    */
  1638.  
  1639.   if (vid_stream->mblock.mb_address - vid_stream->mblock.past_mb_addr > 1) {
  1640.     if (vid_stream->picture.code_type == P_TYPE)
  1641.       ProcessSkippedPFrameMBlocks(vid_stream);
  1642.     else if (vid_stream->picture.code_type == B_TYPE)
  1643.       ProcessSkippedBFrameMBlocks(vid_stream);
  1644.   }
  1645.   /* Set past macroblock address to current macroblock address. */
  1646.   vid_stream->mblock.past_mb_addr = vid_stream->mblock.mb_address;
  1647.  
  1648.   /* Based on picture type decode macroblock type. */
  1649.   switch (vid_stream->picture.code_type) {
  1650.   case I_TYPE:
  1651.     DecodeMBTypeI(mb_quant, mb_motion_forw, mb_motion_back, mb_pattern,
  1652.           vid_stream->mblock.mb_intra);
  1653.     break;
  1654.  
  1655.   case P_TYPE:
  1656.     DecodeMBTypeP(mb_quant, mb_motion_forw, mb_motion_back, mb_pattern,
  1657.           vid_stream->mblock.mb_intra);
  1658.     break;
  1659.  
  1660.   case B_TYPE:
  1661.     DecodeMBTypeB(mb_quant, mb_motion_forw, mb_motion_back, mb_pattern,
  1662.           vid_stream->mblock.mb_intra);
  1663.     break;
  1664.   }
  1665.  
  1666.   /* If quantization flag set, parse off new quantization scale. */
  1667.  
  1668.   if (mb_quant == TRUE) {
  1669.     get_bits5(data);
  1670.     vid_stream->slice.quant_scale = data;
  1671.   }
  1672.   /* If forward motion vectors exist... */
  1673.   if (mb_motion_forw == TRUE) {
  1674.  
  1675.     /* Parse off and decode horizontal forward motion vector. */
  1676.     DecodeMotionVectors(vid_stream->mblock.motion_h_forw_code);
  1677.  
  1678.     /* If horiz. forward r data exists, parse off. */
  1679.  
  1680.     if ((vid_stream->picture.forw_f != 1) &&
  1681.     (vid_stream->mblock.motion_h_forw_code != 0)) {
  1682.       get_bitsn(vid_stream->picture.forw_r_size, data);
  1683.       vid_stream->mblock.motion_h_forw_r = data;
  1684.     }
  1685.     /* Parse off and decode vertical forward motion vector. */
  1686.     DecodeMotionVectors(vid_stream->mblock.motion_v_forw_code);
  1687.  
  1688.     /* If vert. forw. r data exists, parse off. */
  1689.  
  1690.     if ((vid_stream->picture.forw_f != 1) &&
  1691.     (vid_stream->mblock.motion_v_forw_code != 0)) {
  1692.       get_bitsn(vid_stream->picture.forw_r_size, data);
  1693.       vid_stream->mblock.motion_v_forw_r = data;
  1694.     }
  1695.   }
  1696.   /* If back motion vectors exist... */
  1697.   if (mb_motion_back == TRUE) {
  1698.  
  1699.     /* Parse off and decode horiz. back motion vector. */
  1700.     DecodeMotionVectors(vid_stream->mblock.motion_h_back_code);
  1701.  
  1702.     /* If horiz. back r data exists, parse off. */
  1703.  
  1704.     if ((vid_stream->picture.back_f != 1) &&
  1705.     (vid_stream->mblock.motion_h_back_code != 0)) {
  1706.       get_bitsn(vid_stream->picture.back_r_size, data);
  1707.       vid_stream->mblock.motion_h_back_r = data;
  1708.     }
  1709.     /* Parse off and decode vert. back motion vector. */
  1710.     DecodeMotionVectors(vid_stream->mblock.motion_v_back_code);
  1711.  
  1712.     /* If vert. back r data exists, parse off. */
  1713.  
  1714.     if ((vid_stream->picture.back_f != 1) &&
  1715.     (vid_stream->mblock.motion_v_back_code != 0)) {
  1716.       get_bitsn(vid_stream->picture.back_r_size, data);
  1717.       vid_stream->mblock.motion_v_back_r = data;
  1718.     }
  1719.   }
  1720. #ifdef ANALYSIS
  1721.   if (vid_stream->mblock.mb_intra) {
  1722.     stat_a[0].i_mbnum++;
  1723.     mbCBPPtr = stat_a[0].i_mbcbp;
  1724.     mbCoeffPtr = stat_a[0].i_mbcoeff;
  1725.     mbSizePtr = &(stat_a[0].i_mbsize);
  1726.   } else if (mb_motion_back && mb_motion_forw) {
  1727.     stat_a[0].bi_mbnum++;
  1728.     mbCBPPtr = stat_a[0].bi_mbcbp;
  1729.     mbCoeffPtr = stat_a[0].bi_mbcoeff;
  1730.     mbSizePtr = &(stat_a[0].bi_mbsize);
  1731.   } else if (mb_motion_back) {
  1732.     stat_a[0].b_mbnum++;
  1733.     mbCBPPtr = stat_a[0].b_mbcbp;
  1734.     mbCoeffPtr = stat_a[0].b_mbcoeff;
  1735.     mbSizePtr = &(stat_a[0].b_mbsize);
  1736.   } else {
  1737.     stat_a[0].p_mbnum++;
  1738.     mbCBPPtr = stat_a[0].p_mbcbp;
  1739.     mbCoeffPtr = stat_a[0].p_mbcoeff;
  1740.     mbSizePtr = &(stat_a[0].p_mbsize);
  1741.   }
  1742. #endif
  1743.  
  1744.   /* If mblock pattern flag set, parse and decode CBP (code block pattern). */
  1745.   if (mb_pattern == TRUE) {
  1746.     DecodeCBP(vid_stream->mblock.cbp);
  1747.   }
  1748.   /* Otherwise, set CBP to zero. */
  1749.   else
  1750.     vid_stream->mblock.cbp = 0;
  1751.  
  1752.  
  1753. #ifdef ANALYSIS
  1754.   mbCBPPtr[vid_stream->mblock.cbp]++;
  1755. #endif
  1756.  
  1757.   /* Reconstruct motion vectors depending on picture type. */
  1758.   if (vid_stream->picture.code_type == P_TYPE) {
  1759.  
  1760.     /*
  1761.      * If no forw motion vectors, reset previous and current vectors to 0.
  1762.      */
  1763.  
  1764.     if (!mb_motion_forw) {
  1765.       recon_right_for = 0;
  1766.       recon_down_for = 0;
  1767.       vid_stream->mblock.recon_right_for_prev = 0;
  1768.       vid_stream->mblock.recon_down_for_prev = 0;
  1769.     }
  1770.     /*
  1771.      * Otherwise, compute new forw motion vectors. Reset previous vectors to
  1772.      * current vectors.
  1773.      */
  1774.  
  1775.     else {
  1776.       ComputeForwVector(&recon_right_for, &recon_down_for);
  1777.     }
  1778.   }
  1779.   if (vid_stream->picture.code_type == B_TYPE) {
  1780.  
  1781.     /* Reset prev. and current vectors to zero if mblock is intracoded. */
  1782.  
  1783.     if (vid_stream->mblock.mb_intra) {
  1784.       vid_stream->mblock.recon_right_for_prev = 0;
  1785.       vid_stream->mblock.recon_down_for_prev = 0;
  1786.       vid_stream->mblock.recon_right_back_prev = 0;
  1787.       vid_stream->mblock.recon_down_back_prev = 0;
  1788.     } else {
  1789.  
  1790.       /* If no forw vectors, current vectors equal prev. vectors. */
  1791.  
  1792.       if (!mb_motion_forw) {
  1793.     recon_right_for = vid_stream->mblock.recon_right_for_prev;
  1794.     recon_down_for = vid_stream->mblock.recon_down_for_prev;
  1795.       }
  1796.       /*
  1797.        * Otherwise compute forw. vectors. Reset prev vectors to new values.
  1798.        */
  1799.  
  1800.       else {
  1801.         ComputeForwVector(&recon_right_for, &recon_down_for);
  1802.       }
  1803.  
  1804.       /* If no back vectors, set back vectors to prev back vectors. */
  1805.  
  1806.       if (!mb_motion_back) {
  1807.     recon_right_back = vid_stream->mblock.recon_right_back_prev;
  1808.     recon_down_back = vid_stream->mblock.recon_down_back_prev;
  1809.       }
  1810.       /* Otherwise compute new vectors and reset prev. back vectors. */
  1811.  
  1812.       else {
  1813.     ComputeBackVector(&recon_right_back, &recon_down_back);
  1814.       }
  1815.  
  1816.       /*
  1817.        * Store vector existance flags in structure for possible skipped
  1818.        * macroblocks to follow.
  1819.        */
  1820.  
  1821.       vid_stream->mblock.bpict_past_forw = mb_motion_forw;
  1822.       vid_stream->mblock.bpict_past_back = mb_motion_back;
  1823.     }
  1824.   }
  1825.  
  1826.   /* For each possible block in macroblock. */
  1827.   if (ditherType == GRAY_DITHER ||
  1828.       ditherType == MONO_DITHER ||
  1829.       ditherType == MONO_THRESHOLD) {
  1830.     for (mask = 32, i = 0; i < 4; mask >>= 1, i++) {
  1831.  
  1832.       /* If block exists... */
  1833.       if ((vid_stream->mblock.mb_intra) || (vid_stream->mblock.cbp & mask)) {
  1834.     zero_block_flag = 0;
  1835.     ParseReconBlock(i);
  1836.       } else {
  1837.     zero_block_flag = 1;
  1838.       }
  1839.  
  1840.       /* If macroblock is intra coded... */
  1841.       if (vid_stream->mblock.mb_intra) {
  1842.     ReconIMBlock(vid_stream, i);
  1843.       } else if (mb_motion_forw && mb_motion_back) {
  1844.     ReconBiMBlock(vid_stream, i, recon_right_for, recon_down_for,
  1845.               recon_right_back, recon_down_back, zero_block_flag);
  1846.       } else if (mb_motion_forw || (vid_stream->picture.code_type == P_TYPE)) {
  1847.     ReconPMBlock(vid_stream, i, recon_right_for, recon_down_for,
  1848.              zero_block_flag);
  1849.       } else if (mb_motion_back) {
  1850.     ReconBMBlock(vid_stream, i, recon_right_back, recon_down_back,
  1851.              zero_block_flag);
  1852.       }
  1853.     }
  1854.     /* Kill the Chrominace blocks... */
  1855.     if ((vid_stream->mblock.mb_intra) || (vid_stream->mblock.cbp & 0x2)) {
  1856.         ParseAwayBlock(4);
  1857.     }
  1858.     if ((vid_stream->mblock.mb_intra) || (vid_stream->mblock.cbp & 0x1)) {
  1859.         ParseAwayBlock(5);
  1860.     }
  1861.   } else {
  1862.     if ((ditherType == MBORDERED_DITHER) &&
  1863.     (vid_stream->mblock.cbp == 0) &&
  1864.     (vid_stream->picture.code_type == 3) &&
  1865.     (!vid_stream->mblock.mb_intra) &&
  1866.     (!(mb_motion_forw && mb_motion_back))) {
  1867. #if 0
  1868.       MBOrderedDitherDisplayCopy(vid_stream, vid_stream->mblock.mb_address, 
  1869.              mb_motion_forw, recon_right_for, recon_down_for, 
  1870.              mb_motion_back, recon_right_back, recon_down_back,
  1871.              vid_stream->past->display, vid_stream->future->display);
  1872. #endif 
  1873.       ditherFlags[vid_stream->mblock.mb_address] = 0;
  1874.       no_dith_flag = 1;
  1875.     }
  1876.     else {
  1877.       for (mask = 32, i = 0; i < 6; mask >>= 1, i++) {
  1878.     
  1879.     /* If block exists... */
  1880.     if ((vid_stream->mblock.mb_intra) || (vid_stream->mblock.cbp & mask)) {
  1881.       zero_block_flag = 0;
  1882.       ParseReconBlock(i);
  1883.     } else {
  1884.       zero_block_flag = 1;
  1885.     }
  1886.     
  1887.     /* If macroblock is intra coded... */
  1888.     if (vid_stream->mblock.mb_intra) {
  1889.       ReconIMBlock(vid_stream, i);
  1890.     } else if (mb_motion_forw && mb_motion_back) {
  1891.       ReconBiMBlock(vid_stream, i, recon_right_for, recon_down_for,
  1892.             recon_right_back, recon_down_back, zero_block_flag);
  1893.     } else if (mb_motion_forw || (vid_stream->picture.code_type == P_TYPE)) {
  1894.       ReconPMBlock(vid_stream, i, recon_right_for, recon_down_for,
  1895.                zero_block_flag);
  1896.     } else if (mb_motion_back) {
  1897.       ReconBMBlock(vid_stream, i, recon_right_back, recon_down_back,
  1898.                zero_block_flag);
  1899.     }
  1900.       }
  1901.     }
  1902.   }
  1903.  
  1904.   if ((ditherType == MBORDERED_DITHER) && (!no_dith_flag)) {
  1905.     if ((vid_stream->picture.code_type == 2) &&
  1906.     (vid_stream->mblock.cbp == 0) &&
  1907.     (!vid_stream->mblock.mb_intra)) {
  1908. #if 0
  1909.       MBOrderedDitherDisplayCopy(vid_stream, vid_stream->mblock.mb_address,
  1910.                  1, recon_right_for, recon_down_for,
  1911.                  0, 0, 0,
  1912.                  vid_stream->future->display,
  1913.                  (unsigned char *) NULL);
  1914. #endif
  1915.       ditherFlags[vid_stream->mblock.mb_address] = 0;
  1916.     }
  1917.     else {
  1918.       ditherFlags[vid_stream->mblock.mb_address] = 1;
  1919.     }
  1920.   }
  1921.  
  1922.  
  1923.   /* If D Type picture, flush marker bit. */
  1924.   if (vid_stream->picture.code_type == 4)
  1925.     flush_bits(1);
  1926.  
  1927.   /* If macroblock was intracoded, set macroblock past intra address. */
  1928.   if (vid_stream->mblock.mb_intra)
  1929.     vid_stream->mblock.past_intra_addr =
  1930.       vid_stream->mblock.mb_address;
  1931.  
  1932. #ifdef ANALYSIS
  1933.   *mbSizePtr += bitCountRead() - mbSizeCount;
  1934. #endif
  1935.   return PARSE_OK;
  1936. }
  1937.  
  1938.  
  1939.  
  1940. /*
  1941.  *--------------------------------------------------------------
  1942.  *
  1943.  * ReconIMBlock --
  1944.  *
  1945.  *    Reconstructs intra coded macroblock.
  1946.  *
  1947.  * Results:
  1948.  *    None.
  1949.  *
  1950.  * Side effects:
  1951.  *    None.
  1952.  *
  1953.  *--------------------------------------------------------------
  1954.  */
  1955.  
  1956. static void
  1957. ReconIMBlock(vid_stream, bnum)
  1958.   VidStream *vid_stream;
  1959.   int bnum;
  1960. {
  1961.   int mb_row, mb_col, row, col, row_size, rr;
  1962.   unsigned char *dest;
  1963.  
  1964.   /* Calculate macroblock row and column from address. */
  1965.  
  1966.   mb_row = vid_stream->mblock.mb_address / vid_stream->mb_width;
  1967.   mb_col = vid_stream->mblock.mb_address % vid_stream->mb_width;
  1968.  
  1969.  
  1970.   /* If block is luminance block... */
  1971.  
  1972.   if (bnum < 4) {
  1973.  
  1974.     /* Calculate row and col values for upper left pixel of block. */
  1975.  
  1976.     row = mb_row * 16;
  1977.     col = mb_col * 16;
  1978.     if (bnum > 1)
  1979.       row += 8;
  1980.     if (bnum % 2)
  1981.       col += 8;
  1982.  
  1983.     /* Set dest to luminance plane of current pict image. */
  1984.  
  1985.     dest = vid_stream->current->luminance;
  1986.  
  1987.     /* Establish row size. */
  1988.  
  1989.     row_size = vid_stream->mb_width * 16;
  1990.   }
  1991.   /* Otherwise if block is Cr block... */
  1992.  
  1993.   else if (bnum == 4) {
  1994.  
  1995.     /* Set dest to Cr plane of current pict image. */
  1996.  
  1997.     dest = vid_stream->current->Cr;
  1998.  
  1999.     /* Establish row size. */
  2000.  
  2001.     row_size = vid_stream->mb_width * 8;
  2002.  
  2003.     /* Calculate row,col for upper left pixel of block. */
  2004.  
  2005.     row = mb_row * 8;
  2006.     col = mb_col * 8;
  2007.   }
  2008.   /* Otherwise block is Cb block, and ... */
  2009.  
  2010.   else {
  2011.  
  2012.     /* Set dest to Cb plane of current pict image. */
  2013.  
  2014.     dest = vid_stream->current->Cb;
  2015.  
  2016.     /* Establish row size. */
  2017.  
  2018.     row_size = vid_stream->mb_width * 8;
  2019.  
  2020.     /* Calculate row,col for upper left pixel value of block. */
  2021.  
  2022.     row = mb_row * 8;
  2023.     col = mb_col * 8;
  2024.   }
  2025.  
  2026.   /*
  2027.    * For each pixel in block, set to cropped reconstructed value from inverse
  2028.    * dct.
  2029.    */
  2030.   {
  2031.     short *sp = &vid_stream->block.dct_recon[0][0];
  2032.     unsigned char *cm = cropTbl + MAX_NEG_CROP;
  2033.     dest += row * row_size + col;
  2034.     for (rr = 0; rr < 4; rr++, sp += 16, dest += row_size) {
  2035.       dest[0] = cm[sp[0]];
  2036.       assertCrop(sp[0]);
  2037.       dest[1] = cm[sp[1]];
  2038.       assertCrop(sp[1]);
  2039.       dest[2] = cm[sp[2]];
  2040.       assertCrop(sp[2]);
  2041.       dest[3] = cm[sp[3]];
  2042.       assertCrop(sp[3]);
  2043.       dest[4] = cm[sp[4]];
  2044.       assertCrop(sp[4]);
  2045.       dest[5] = cm[sp[5]];
  2046.       assertCrop(sp[5]);
  2047.       dest[6] = cm[sp[6]];
  2048.       assertCrop(sp[6]);
  2049.       dest[7] = cm[sp[7]];
  2050.       assertCrop(sp[7]);
  2051.  
  2052.       dest += row_size;
  2053.       dest[0] = cm[sp[8]];
  2054.       assertCrop(sp[8]);
  2055.       dest[1] = cm[sp[9]];
  2056.       assertCrop(sp[9]);
  2057.       dest[2] = cm[sp[10]];
  2058.       assertCrop(sp[10]);
  2059.       dest[3] = cm[sp[11]];
  2060.       assertCrop(sp[11]);
  2061.       dest[4] = cm[sp[12]];
  2062.       assertCrop(sp[12]);
  2063.       dest[5] = cm[sp[13]];
  2064.       assertCrop(sp[13]);
  2065.       dest[6] = cm[sp[14]];
  2066.       assertCrop(sp[14]);
  2067.       dest[7] = cm[sp[15]];
  2068.       assertCrop(sp[15]);
  2069.     }
  2070.   }
  2071. }
  2072.  
  2073.  
  2074.  
  2075. /*
  2076.  *--------------------------------------------------------------
  2077.  *
  2078.  * ReconPMBlock --
  2079.  *
  2080.  *    Reconstructs forward predicted macroblocks.
  2081.  *
  2082.  * Results:
  2083.  *      None.
  2084.  *
  2085.  * Side effects:
  2086.  *      None.
  2087.  *
  2088.  *--------------------------------------------------------------
  2089.  */
  2090.  
  2091. static void
  2092. ReconPMBlock(vid_stream, bnum, recon_right_for, recon_down_for, zflag)
  2093.   VidStream *vid_stream;
  2094.   int bnum, recon_right_for, recon_down_for, zflag;
  2095. {
  2096.   int mb_row, mb_col, row, col, row_size, rr;
  2097.   unsigned char *dest, *past;
  2098.   static int right_for, down_for, right_half_for, down_half_for;
  2099.   unsigned char *rindex1, *rindex2;
  2100.   unsigned char *index;
  2101.   short int *blockvals;
  2102.  
  2103. #ifdef LOOSE_MPEG
  2104.   int maxx, maxy;
  2105.   int illegalBlock = 0;
  2106.   int row_start, row_end, rfirst, rlast, col_start, col_end, cfirst, clast;
  2107. #endif
  2108.  
  2109.   /* Calculate macroblock row and column from address. */
  2110.  
  2111.   mb_row = vid_stream->mblock.mb_address / vid_stream->mb_width;
  2112.   mb_col = vid_stream->mblock.mb_address % vid_stream->mb_width;
  2113.  
  2114.   if (bnum < 4) {
  2115.  
  2116.     /* Calculate right_for, down_for motion vectors. */
  2117.  
  2118.     right_for = recon_right_for >> 1;
  2119.     down_for = recon_down_for >> 1;
  2120.     right_half_for = recon_right_for & 0x1;
  2121.     down_half_for = recon_down_for & 0x1;
  2122.  
  2123.     /* Set dest to luminance plane of current pict image. */
  2124.  
  2125.     dest = vid_stream->current->luminance;
  2126.  
  2127.     if (vid_stream->picture.code_type == B_TYPE) {
  2128.       if (vid_stream->past != NULL)
  2129.     past = vid_stream->past->luminance;
  2130.     } else {
  2131.  
  2132.       /* Set predicitive frame to current future frame. */
  2133.  
  2134.       if (vid_stream->future != NULL)
  2135.     past = vid_stream->future->luminance;
  2136.     }
  2137.  
  2138.     /* Establish row size. */
  2139.  
  2140.     row_size = vid_stream->mb_width << 4;
  2141.  
  2142.     /* Calculate row,col of upper left pixel in block. */
  2143.  
  2144.     row = mb_row << 4;
  2145.     col = mb_col << 4;
  2146.     if (bnum > 1)
  2147.       row += 8;
  2148.     if (bnum % 2)
  2149.       col += 8;
  2150.  
  2151. #ifdef LOOSE_MPEG
  2152.     /* Check for block illegality. */
  2153.  
  2154.     maxx = lmaxx; maxy = lmaxy;
  2155.  
  2156.     if (row + down_for + 7 > maxy) illegalBlock |= 0x4;
  2157.     else if (row + down_for < 0)  illegalBlock |= 0x1;
  2158.     
  2159.     if (col + right_for + 7 > maxx) illegalBlock |= 0x2;
  2160.     else if (col + right_for < 0) illegalBlock |= 0x8;
  2161.  
  2162. #endif
  2163.   }
  2164.   /* Otherwise, block is NOT luminance block, ... */
  2165.  
  2166.   else {
  2167.  
  2168.     /* Construct motion vectors. */
  2169.  
  2170.     recon_right_for /= 2;
  2171.     recon_down_for /= 2;
  2172.     right_for = recon_right_for >> 1;
  2173.     down_for = recon_down_for >> 1;
  2174.     right_half_for = recon_right_for & 0x1;
  2175.     down_half_for = recon_down_for & 0x1;
  2176.  
  2177.     /* Establish row size. */
  2178.  
  2179.     row_size = vid_stream->mb_width << 3;
  2180.  
  2181.     /* Calculate row,col of upper left pixel in block. */
  2182.  
  2183.     row = mb_row << 3;
  2184.     col = mb_col << 3;
  2185.  
  2186. #ifdef LOOSE_MPEG
  2187.     /* Check for block illegality. */
  2188.  
  2189.     maxx = cmaxx; maxy = cmaxy;
  2190.  
  2191.     if (row + down_for  + 7 > maxy) illegalBlock |= 0x4;
  2192.     else if (row + down_for < 0) illegalBlock |= 0x1;
  2193.  
  2194.     if (col + right_for  + 7 > maxx) illegalBlock  |= 0x2;
  2195.     else if (col + right_for < 0) illegalBlock |= 0x8;
  2196.  
  2197. #endif
  2198.  
  2199.     /* If block is Cr block... */
  2200.  
  2201.     if (bnum == 4) {
  2202.  
  2203.       /* Set dest to Cr plane of current pict image. */
  2204.  
  2205.       dest = vid_stream->current->Cr;
  2206.  
  2207.       if (vid_stream->picture.code_type == B_TYPE) {
  2208.  
  2209.     if (vid_stream->past != NULL)
  2210.       past = vid_stream->past->Cr;
  2211.       } else {
  2212.     if (vid_stream->future != NULL)
  2213.       past = vid_stream->future->Cr;
  2214.       }
  2215.     }
  2216.     /* Otherwise, block is Cb block... */
  2217.  
  2218.     else {
  2219.  
  2220.       /* Set dest to Cb plane of current pict image. */
  2221.  
  2222.       dest = vid_stream->current->Cb;
  2223.  
  2224.       if (vid_stream->picture.code_type == B_TYPE) {
  2225.     if (vid_stream->past != NULL)
  2226.       past = vid_stream->past->Cb;
  2227.       } else {
  2228.     if (vid_stream->future != NULL)
  2229.       past = vid_stream->future->Cb;
  2230.       }
  2231.     }
  2232.   }
  2233.  
  2234.   /* For each pixel in block... */
  2235.  
  2236. #ifdef LOOSE_MPEG
  2237.  
  2238.   if (illegalBlock) {
  2239.     if (illegalBlock & 0x1) {
  2240.       row_start = 0;
  2241.       row_end = row+down_for+8;
  2242.       rfirst = rlast = 8 - row_end;
  2243.     }
  2244.     else if (illegalBlock & 0x4) {
  2245.       row_start = row + down_for;
  2246.       row_end = maxy+1;
  2247.       rlast = row_end - row_start - 1;
  2248.       rfirst = 0;
  2249.     }
  2250.     else {
  2251.       row_start = row+down_for;
  2252.       row_end = row_start+8;
  2253.       rfirst = 0;
  2254.     }
  2255.  
  2256.     if (illegalBlock & 0x8) {
  2257.       col_start = 0;
  2258.       col_end = col + right_for + 8;
  2259.       cfirst = clast = 8 - col_end;
  2260.     }
  2261.     else if (illegalBlock & 0x2) {
  2262.       col_start = col + right_for;
  2263.       col_end = maxx + 1;
  2264.       clast = col_end - col_start - 1;
  2265.       cfirst = 0;
  2266.     }
  2267.     else {
  2268.       col_start = col + right_for;
  2269.       col_end = col_start + 8;
  2270.       cfirst = 0;
  2271.     }
  2272.  
  2273.     for (rr = row_start; rr < row_end; rr++) {
  2274.       rindex1 = past + (rr * row_size) + col_start;
  2275.       index = dest + ((row + rfirst) * row_size) + col + cfirst;
  2276.       for (cc = col_start; cc < col_end; cc++) {
  2277.     *index++ = *rindex1++;
  2278.       }
  2279.     }
  2280.  
  2281.     if (illegalBlock & 0x1) {
  2282.       for (rr = rlast -1; rr >=0; rr--) {
  2283.     index = dest + ((row + rr) * row_size) + col;
  2284.     rindex1 = dest + ((row + rlast) * row_size) + col;
  2285.     for (cc = 0; cc < 8; cc ++) {
  2286.       *index++ = *rindex1++;
  2287.     }
  2288.       }
  2289.     }
  2290.     else if (illegalBlock & 0x4) {
  2291.       for (rr = rlast+1; rr < 8; rr++) {
  2292.     index = dest + ((row + rr) * row_size) + col;
  2293.     rindex1 = dest + ((row + rlast) * row_size) + col;
  2294.     for (cc = 0; cc < 8; cc ++) {
  2295.       *index++ = *rindex1++;
  2296.     }
  2297.       }
  2298.     }
  2299.  
  2300.     if (illegalBlock & 0x2) {
  2301.       for (cc = clast+1; cc < 8; cc++) {
  2302.     index = dest + (row * row_size) + (col + cc);
  2303.     rindex1 = dest + (row * row_size) + (col + clast);
  2304.     for (rr = 0; rr < 8; rr++) {
  2305.       *index = *rindex1;
  2306.       index += row_size;
  2307.       rindex1 += row_size;
  2308.     }
  2309.       }
  2310.     }
  2311.     else if (illegalBlock & 0x8) {
  2312.       for (cc = clast-1; cc >= 0; cc--) {
  2313.     index = dest + (row * row_size) + (col + cc);
  2314.     rindex1 = dest + (row * row_size) + (col + clast);
  2315.     for (rr = 0; rr < 8; rr++) {
  2316.       *index = *rindex1;
  2317.       index += row_size;
  2318.       rindex1 += row_size;
  2319.     }
  2320.       }
  2321.     }
  2322.  
  2323.     if (!zflag) {
  2324.       for (rr = 0; rr < 8; rr++) {
  2325.     index = dest + (row*row_size) + col;
  2326.     blockvals = &(vid_stream->block.dct_recon[rr][0]);
  2327.     index[0] += blockvals[0];
  2328.     index[1] += blockvals[1];
  2329.     index[2] += blockvals[2];
  2330.     index[3] += blockvals[3];
  2331.     index[4] += blockvals[4];
  2332.     index[5] += blockvals[5];
  2333.     index[6] += blockvals[6];
  2334.     index[7] += blockvals[7];
  2335.       }
  2336.     }
  2337.   }
  2338.   else {
  2339.  
  2340. #endif
  2341.  
  2342.     index = dest + (row * row_size) + col;
  2343.     rindex1 = past + (row + down_for) * row_size + col + right_for;
  2344.     
  2345.     blockvals = &(vid_stream->block.dct_recon[0][0]);
  2346.     
  2347.     /*
  2348.      * Calculate predictive pixel value based on motion vectors and copy to
  2349.      * dest plane.
  2350.      */
  2351.     
  2352.     if ((!down_half_for) && (!right_half_for)) {
  2353.       unsigned char *cm = cropTbl + MAX_NEG_CROP;
  2354.       if (!zflag)
  2355.     for (rr = 0; rr < 4; rr++) {
  2356.       index[0] = cm[(int) rindex1[0] + (int) blockvals[0]];
  2357.       index[1] = cm[(int) rindex1[1] + (int) blockvals[1]];
  2358.       index[2] = cm[(int) rindex1[2] + (int) blockvals[2]];
  2359.       index[3] = cm[(int) rindex1[3] + (int) blockvals[3]];
  2360.       index[4] = cm[(int) rindex1[4] + (int) blockvals[4]];
  2361.       index[5] = cm[(int) rindex1[5] + (int) blockvals[5]];
  2362.       index[6] = cm[(int) rindex1[6] + (int) blockvals[6]];
  2363.       index[7] = cm[(int) rindex1[7] + (int) blockvals[7]];
  2364.       index += row_size;
  2365.       rindex1 += row_size;
  2366.       
  2367.       index[0] = cm[(int) rindex1[0] + (int) blockvals[8]];
  2368.       index[1] = cm[(int) rindex1[1] + (int) blockvals[9]];
  2369.       index[2] = cm[(int) rindex1[2] + (int) blockvals[10]];
  2370.       index[3] = cm[(int) rindex1[3] + (int) blockvals[11]];
  2371.       index[4] = cm[(int) rindex1[4] + (int) blockvals[12]];
  2372.       index[5] = cm[(int) rindex1[5] + (int) blockvals[13]];
  2373.       index[6] = cm[(int) rindex1[6] + (int) blockvals[14]];
  2374.       index[7] = cm[(int) rindex1[7] + (int) blockvals[15]];
  2375.       blockvals += 16;
  2376.       index += row_size;
  2377.       rindex1 += row_size;
  2378.     }
  2379.       else {
  2380.     if (right_for & 0x1) {
  2381.       /* No alignment, use bye copy */
  2382.       for (rr = 0; rr < 4; rr++) {
  2383.         index[0] = rindex1[0];
  2384.         index[1] = rindex1[1];
  2385.         index[2] = rindex1[2];
  2386.         index[3] = rindex1[3];
  2387.         index[4] = rindex1[4];
  2388.         index[5] = rindex1[5];
  2389.         index[6] = rindex1[6];
  2390.         index[7] = rindex1[7];
  2391.         index += row_size;
  2392.         rindex1 += row_size;
  2393.         
  2394.         index[0] = rindex1[0];
  2395.         index[1] = rindex1[1];
  2396.         index[2] = rindex1[2];
  2397.         index[3] = rindex1[3];
  2398.         index[4] = rindex1[4];
  2399.         index[5] = rindex1[5];
  2400.         index[6] = rindex1[6];
  2401.         index[7] = rindex1[7];
  2402.         index += row_size;
  2403.         rindex1 += row_size;
  2404.       }
  2405.     } else if (right_for & 0x2) {
  2406.       /* Half-word bit aligned, use 16 bit copy */
  2407.       short *src = (short *)rindex1;
  2408.       short *dest = (short *)index;
  2409.       row_size >>= 1;
  2410.       for (rr = 0; rr < 4; rr++) {
  2411.         dest[0] = src[0];
  2412.         dest[1] = src[1];
  2413.         dest[2] = src[2];
  2414.         dest[3] = src[3];
  2415.         dest += row_size;
  2416.         src += row_size;
  2417.         
  2418.         dest[0] = src[0];
  2419.         dest[1] = src[1];
  2420.         dest[2] = src[2];
  2421.         dest[3] = src[3];
  2422.         dest += row_size;
  2423.         src += row_size;
  2424.       }
  2425.     } else {
  2426.       /* Word aligned, use 32 bit copy */
  2427.       int *src = (int *)rindex1;
  2428.       int *dest = (int *)index;
  2429.       row_size >>= 2;
  2430.       for (rr = 0; rr < 4; rr++) {
  2431.         dest[0] = src[0];
  2432.         dest[1] = src[1];
  2433.         dest += row_size;
  2434.         src += row_size;
  2435.         
  2436.         dest[0] = src[0];
  2437.         dest[1] = src[1];
  2438.         dest += row_size;
  2439.         src += row_size;
  2440.       }
  2441.     }
  2442.       }
  2443.     } else {
  2444.       unsigned char *cm = cropTbl + MAX_NEG_CROP;
  2445.       rindex2 = rindex1 + right_half_for + (down_half_for * row_size);
  2446.       if (!zflag)
  2447.     for (rr = 0; rr < 4; rr++) {
  2448.       index[0] = cm[((int) (rindex1[0] + rindex2[0]) >> 1) + blockvals[0]];
  2449.       index[1] = cm[((int) (rindex1[1] + rindex2[1]) >> 1) + blockvals[1]];
  2450.       index[2] = cm[((int) (rindex1[2] + rindex2[2]) >> 1) + blockvals[2]];
  2451.       index[3] = cm[((int) (rindex1[3] + rindex2[3]) >> 1) + blockvals[3]];
  2452.       index[4] = cm[((int) (rindex1[4] + rindex2[4]) >> 1) + blockvals[4]];
  2453.       index[5] = cm[((int) (rindex1[5] + rindex2[5]) >> 1) + blockvals[5]];
  2454.       index[6] = cm[((int) (rindex1[6] + rindex2[6]) >> 1) + blockvals[6]];
  2455.       index[7] = cm[((int) (rindex1[7] + rindex2[7]) >> 1) + blockvals[7]];
  2456.       index += row_size;
  2457.       rindex1 += row_size;
  2458.       rindex2 += row_size;
  2459.       
  2460.       index[0] = cm[((int) (rindex1[0] + rindex2[0]) >> 1) + blockvals[8]];
  2461.       index[1] = cm[((int) (rindex1[1] + rindex2[1]) >> 1) + blockvals[9]];
  2462.       index[2] = cm[((int) (rindex1[2] + rindex2[2]) >> 1) + blockvals[10]];
  2463.       index[3] = cm[((int) (rindex1[3] + rindex2[3]) >> 1) + blockvals[11]];
  2464.       index[4] = cm[((int) (rindex1[4] + rindex2[4]) >> 1) + blockvals[12]];
  2465.       index[5] = cm[((int) (rindex1[5] + rindex2[5]) >> 1) + blockvals[13]];
  2466.       index[6] = cm[((int) (rindex1[6] + rindex2[6]) >> 1) + blockvals[14]];
  2467.       index[7] = cm[((int) (rindex1[7] + rindex2[7]) >> 1) + blockvals[15]];
  2468.       blockvals += 16;
  2469.       index += row_size;
  2470.       rindex1 += row_size;
  2471.       rindex2 += row_size;
  2472.     }
  2473.       else
  2474.     for (rr = 0; rr < 4; rr++) {
  2475.       index[0] = (int) (rindex1[0] + rindex2[0]) >> 1;
  2476.       index[1] = (int) (rindex1[1] + rindex2[1]) >> 1;
  2477.       index[2] = (int) (rindex1[2] + rindex2[2]) >> 1;
  2478.       index[3] = (int) (rindex1[3] + rindex2[3]) >> 1;
  2479.       index[4] = (int) (rindex1[4] + rindex2[4]) >> 1;
  2480.       index[5] = (int) (rindex1[5] + rindex2[5]) >> 1;
  2481.       index[6] = (int) (rindex1[6] + rindex2[6]) >> 1;
  2482.       index[7] = (int) (rindex1[7] + rindex2[7]) >> 1;
  2483.       index += row_size;
  2484.       rindex1 += row_size;
  2485.       rindex2 += row_size;
  2486.       
  2487.       index[0] = (int) (rindex1[0] + rindex2[0]) >> 1;
  2488.       index[1] = (int) (rindex1[1] + rindex2[1]) >> 1;
  2489.       index[2] = (int) (rindex1[2] + rindex2[2]) >> 1;
  2490.       index[3] = (int) (rindex1[3] + rindex2[3]) >> 1;
  2491.       index[4] = (int) (rindex1[4] + rindex2[4]) >> 1;
  2492.       index[5] = (int) (rindex1[5] + rindex2[5]) >> 1;
  2493.       index[6] = (int) (rindex1[6] + rindex2[6]) >> 1;
  2494.       index[7] = (int) (rindex1[7] + rindex2[7]) >> 1;
  2495.       index += row_size;
  2496.       rindex1 += row_size;
  2497.       rindex2 += row_size;
  2498.     }
  2499.     }
  2500.  
  2501. #ifdef LOOSE_MPEG
  2502.   }
  2503. #endif
  2504. }
  2505.  
  2506.  
  2507. /*
  2508.  *--------------------------------------------------------------
  2509.  *
  2510.  * ReconBMBlock --
  2511.  *
  2512.  *    Reconstructs back predicted macroblocks.
  2513.  *
  2514.  * Results:
  2515.  *      None.
  2516.  *
  2517.  * Side effects:
  2518.  *      None.
  2519.  *
  2520.  *--------------------------------------------------------------
  2521.  */
  2522.  
  2523. static void
  2524. ReconBMBlock(vid_stream, bnum, recon_right_back, recon_down_back, zflag)
  2525.   VidStream *vid_stream;
  2526.   int bnum, recon_right_back, recon_down_back, zflag;
  2527. {
  2528.   int mb_row, mb_col, row, col, row_size, rr;
  2529.   unsigned char *dest, *future;
  2530.   int right_back, down_back, right_half_back, down_half_back;
  2531.   unsigned char *rindex1, *rindex2;
  2532.   unsigned char *index;
  2533.   short int *blockvals;
  2534.  
  2535. #ifdef LOOSE_MPEG
  2536.   int illegalBlock = 0;
  2537.   int maxx, maxy;
  2538.   int row_start, row_end, rlast, rfirst, col_start, col_end, clast, cfirst;
  2539. #endif
  2540.  
  2541.   /* Calculate macroblock row and column from address. */
  2542.  
  2543.   mb_row = vid_stream->mblock.mb_address / vid_stream->mb_width;
  2544.   mb_col = vid_stream->mblock.mb_address % vid_stream->mb_width;
  2545.  
  2546.   /* If block is luminance block... */
  2547.  
  2548.   if (bnum < 4) {
  2549.  
  2550.     /* Calculate right_back, down_bakc motion vectors. */
  2551.  
  2552.     right_back = recon_right_back >> 1;
  2553.     down_back = recon_down_back >> 1;
  2554.     right_half_back = recon_right_back & 0x1;
  2555.     down_half_back = recon_down_back & 0x1;
  2556.  
  2557.     /* Set dest to luminance plane of current pict image. */
  2558.  
  2559.     dest = vid_stream->current->luminance;
  2560.  
  2561.     /*
  2562.      * If future frame exists, set future to luminance plane of future frame.
  2563.      */
  2564.  
  2565.     if (vid_stream->future != NULL)
  2566.       future = vid_stream->future->luminance;
  2567.  
  2568.     /* Establish row size. */
  2569.  
  2570.     row_size = vid_stream->mb_width << 4;
  2571.  
  2572.     /* Calculate row,col of upper left pixel in block. */
  2573.  
  2574.     row = mb_row << 4;
  2575.     col = mb_col << 4;
  2576.     if (bnum > 1)
  2577.       row += 8;
  2578.     if (bnum % 2)
  2579.       col += 8;
  2580.  
  2581. #ifdef LOOSE_MPEG
  2582.  
  2583.     /* Check for block illegality. */
  2584.  
  2585.     maxx = lmaxx; maxy = lmaxy;
  2586.  
  2587.     if (row + down_back + 7 > maxy) illegalBlock |= 0x4;
  2588.     else if (row + down_back < 0)  illegalBlock |= 0x1;
  2589.     
  2590.     if (col + right_back + 7 > maxx) illegalBlock |= 0x2;
  2591.     else if (col + right_back < 0) illegalBlock |= 0x8;
  2592.  
  2593. #endif
  2594.  
  2595.   }
  2596.   /* Otherwise, block is NOT luminance block, ... */
  2597.  
  2598.   else {
  2599.  
  2600.     /* Construct motion vectors. */
  2601.  
  2602.     recon_right_back /= 2;
  2603.     recon_down_back /= 2;
  2604.     right_back = recon_right_back >> 1;
  2605.     down_back = recon_down_back >> 1;
  2606.     right_half_back = recon_right_back & 0x1;
  2607.     down_half_back = recon_down_back & 0x1;
  2608.  
  2609.     /* Establish row size. */
  2610.  
  2611.     row_size = vid_stream->mb_width << 3;
  2612.  
  2613.     /* Calculate row,col of upper left pixel in block. */
  2614.  
  2615.     row = mb_row << 3;
  2616.     col = mb_col << 3;
  2617.  
  2618. #ifdef LOOSE_MPEG
  2619.  
  2620.     /* Check for block illegality. */
  2621.  
  2622.     maxx = cmaxx; maxy = cmaxy;
  2623.  
  2624.     if (row + down_back + 7 > maxy) illegalBlock |= 0x4;
  2625.     else if (row + down_back < 0) illegalBlock |= 0x1;
  2626.  
  2627.     if (col + right_back + 7 > maxx) illegalBlock  |= 0x2;
  2628.     else if (col + right_back < 0) illegalBlock |= 0x8;
  2629.  
  2630. #endif
  2631.  
  2632.     /* If block is Cr block... */
  2633.  
  2634.     if (bnum == 4) {
  2635.  
  2636.       /* Set dest to Cr plane of current pict image. */
  2637.  
  2638.       dest = vid_stream->current->Cr;
  2639.  
  2640.       /*
  2641.        * If future frame exists, set future to Cr plane of future image.
  2642.        */
  2643.  
  2644.       if (vid_stream->future != NULL)
  2645.     future = vid_stream->future->Cr;
  2646.     }
  2647.     /* Otherwise, block is Cb block... */
  2648.  
  2649.     else {
  2650.  
  2651.       /* Set dest to Cb plane of current pict image. */
  2652.  
  2653.       dest = vid_stream->current->Cb;
  2654.  
  2655.       /*
  2656.        * If future frame exists, set future to Cb plane of future frame.
  2657.        */
  2658.  
  2659.       if (vid_stream->future != NULL)
  2660.     future = vid_stream->future->Cb;
  2661.     }
  2662.   }
  2663.  
  2664.   /* For each pixel in block do... */
  2665.  
  2666. #ifdef LOOSE_MPEG
  2667.  
  2668.   if (illegalBlock) {
  2669.     if (illegalBlock & 0x1) {
  2670.       row_start = 0;
  2671.       row_end = row+down_back+8;
  2672.       rfirst = rlast = 8 - row_end;
  2673.     }
  2674.     else if (illegalBlock & 0x4) {
  2675.       row_start = row + down_back;
  2676.       row_end = maxy+1;
  2677.       rlast = row_end - row_start - 1;
  2678.       rfirst = 0;
  2679.     }
  2680.     else {
  2681.       row_start = row+down_back;
  2682.       row_end = row_start+8;
  2683.       rfirst = 0;
  2684.     }
  2685.  
  2686.     if (illegalBlock & 0x8) {
  2687.       col_start = 0;
  2688.       col_end = col + right_back + 8;
  2689.       cfirst = clast = 8 - col_end;
  2690.     }
  2691.     else if (illegalBlock & 0x2) {
  2692.       col_start = col + right_back;
  2693.       col_end = maxx + 1;
  2694.       clast = col_end - col_start - 1;
  2695.       cfirst = 0;
  2696.     }
  2697.     else {
  2698.       col_start = col + right_back;
  2699.       col_end = col_start + 8;
  2700.       cfirst = 0;
  2701.     }
  2702.  
  2703.     for (rr = row_start; rr < row_end; rr++) {
  2704.       rindex1 = future + (rr * row_size) + col_start;
  2705.       index = dest + ((row + rfirst) * row_size) + col + cfirst;
  2706.       for (cc = col_start; cc < col_end; cc++) {
  2707.     *index++ = *rindex1++;
  2708.       }
  2709.     }
  2710.  
  2711.     if (illegalBlock & 0x1) {
  2712.       for (rr = rlast -1; rr >=0; rr--) {
  2713.     index = dest + ((row + rr) * row_size) + col;
  2714.     rindex1 = dest + ((row + rlast) * row_size) + col;
  2715.     for (cc = 0; cc < 8; cc ++) {
  2716.       *index++ = *rindex1++;
  2717.     }
  2718.       }
  2719.     }
  2720.     else if (illegalBlock & 0x4) {
  2721.       for (rr = rlast+1; rr < 8; rr++) {
  2722.     index = dest + ((row + rr) * row_size) + col;
  2723.     rindex1 = dest + ((row + rlast) * row_size) + col;
  2724.     for (cc = 0; cc < 8; cc ++) {
  2725.       *index++ = *rindex1++;
  2726.     }
  2727.       }
  2728.     }
  2729.  
  2730.     if (illegalBlock & 0x2) {
  2731.       for (cc = clast+1; cc < 8; cc++) {
  2732.     index = dest + (row * row_size) + (col + cc);
  2733.     rindex1 = dest + (row * row_size) + (col + clast);
  2734.     for (rr = 0; rr < 8; rr++) {
  2735.       *index = *rindex1;
  2736.       index += row_size;
  2737.       rindex1 += row_size;
  2738.     }
  2739.       }
  2740.     }
  2741.     else if (illegalBlock & 0x8) {
  2742.       for (cc = clast-1; cc >= 0; cc--) {
  2743.     index = dest + (row * row_size) + (col + cc);
  2744.     rindex1 = dest + (row * row_size) + (col + clast);
  2745.     for (rr = 0; rr < 8; rr++) {
  2746.       *index = *rindex1;
  2747.       index += row_size;
  2748.       rindex1 += row_size;
  2749.     }
  2750.       }
  2751.     }
  2752.  
  2753.     if (!zflag) {
  2754.       for (rr = 0; rr < 8; rr++) {
  2755.     index = dest + (row*row_size) + col;
  2756.     blockvals = &(vid_stream->block.dct_recon[rr][0]);
  2757.     index[0] += blockvals[0];
  2758.     index[1] += blockvals[1];
  2759.     index[2] += blockvals[2];
  2760.     index[3] += blockvals[3];
  2761.     index[4] += blockvals[4];
  2762.     index[5] += blockvals[5];
  2763.     index[6] += blockvals[6];
  2764.     index[7] += blockvals[7];
  2765.       }
  2766.     }
  2767.   }
  2768.   else {
  2769.  
  2770. #endif
  2771.     
  2772.     index = dest + (row * row_size) + col;
  2773.     rindex1 = future + (row + down_back) * row_size + col + right_back;
  2774.  
  2775.     blockvals = &(vid_stream->block.dct_recon[0][0]);
  2776.  
  2777.     if ((!right_half_back) && (!down_half_back)) {
  2778.       unsigned char *cm = cropTbl + MAX_NEG_CROP;
  2779.       if (!zflag)
  2780.     for (rr = 0; rr < 4; rr++) {
  2781.       index[0] = cm[(int) rindex1[0] + (int) blockvals[0]];
  2782.       index[1] = cm[(int) rindex1[1] + (int) blockvals[1]];
  2783.       index[2] = cm[(int) rindex1[2] + (int) blockvals[2]];
  2784.       index[3] = cm[(int) rindex1[3] + (int) blockvals[3]];
  2785.       index[4] = cm[(int) rindex1[4] + (int) blockvals[4]];
  2786.       index[5] = cm[(int) rindex1[5] + (int) blockvals[5]];
  2787.       index[6] = cm[(int) rindex1[6] + (int) blockvals[6]];
  2788.       index[7] = cm[(int) rindex1[7] + (int) blockvals[7]];
  2789.       index += row_size;
  2790.       rindex1 += row_size;
  2791.       
  2792.       index[0] = cm[(int) rindex1[0] + (int) blockvals[8]];
  2793.       index[1] = cm[(int) rindex1[1] + (int) blockvals[9]];
  2794.       index[2] = cm[(int) rindex1[2] + (int) blockvals[10]];
  2795.       index[3] = cm[(int) rindex1[3] + (int) blockvals[11]];
  2796.       index[4] = cm[(int) rindex1[4] + (int) blockvals[12]];
  2797.       index[5] = cm[(int) rindex1[5] + (int) blockvals[13]];
  2798.       index[6] = cm[(int) rindex1[6] + (int) blockvals[14]];
  2799.       index[7] = cm[(int) rindex1[7] + (int) blockvals[15]];
  2800.       blockvals += 16;
  2801.       index += row_size;
  2802.       rindex1 += row_size;
  2803.     }
  2804.       else {
  2805.     if (right_back & 0x1) {
  2806.       /* No alignment, use bye copy */
  2807.       for (rr = 0; rr < 4; rr++) {
  2808.         index[0] = rindex1[0];
  2809.         index[1] = rindex1[1];
  2810.         index[2] = rindex1[2];
  2811.         index[3] = rindex1[3];
  2812.         index[4] = rindex1[4];
  2813.         index[5] = rindex1[5];
  2814.         index[6] = rindex1[6];
  2815.         index[7] = rindex1[7];
  2816.         index += row_size;
  2817.         rindex1 += row_size;
  2818.         
  2819.         index[0] = rindex1[0];
  2820.         index[1] = rindex1[1];
  2821.         index[2] = rindex1[2];
  2822.         index[3] = rindex1[3];
  2823.         index[4] = rindex1[4];
  2824.         index[5] = rindex1[5];
  2825.         index[6] = rindex1[6];
  2826.         index[7] = rindex1[7];
  2827.         index += row_size;
  2828.         rindex1 += row_size;
  2829.       }
  2830.     } else if (right_back & 0x2) {
  2831.       /* Half-word bit aligned, use 16 bit copy */
  2832.       short *src = (short *)rindex1;
  2833.       short *dest = (short *)index;
  2834.       row_size >>= 1;
  2835.       for (rr = 0; rr < 4; rr++) {
  2836.         dest[0] = src[0];
  2837.         dest[1] = src[1];
  2838.         dest[2] = src[2];
  2839.         dest[3] = src[3];
  2840.         dest += row_size;
  2841.         src += row_size;
  2842.         
  2843.         dest[0] = src[0];
  2844.         dest[1] = src[1];
  2845.         dest[2] = src[2];
  2846.         dest[3] = src[3];
  2847.         dest += row_size;
  2848.         src += row_size;
  2849.       }
  2850.     } else {
  2851.       /* Word aligned, use 32 bit copy */
  2852.       int *src = (int *)rindex1;
  2853.       int *dest = (int *)index;
  2854.       row_size >>= 2;
  2855.       for (rr = 0; rr < 4; rr++) {
  2856.         dest[0] = src[0];
  2857.         dest[1] = src[1];
  2858.         dest += row_size;
  2859.         src += row_size;
  2860.         
  2861.         dest[0] = src[0];
  2862.         dest[1] = src[1];
  2863.         dest += row_size;
  2864.         src += row_size;
  2865.       }
  2866.     }
  2867.       }
  2868.     } else {
  2869.       unsigned char *cm = cropTbl + MAX_NEG_CROP;
  2870.       rindex2 = rindex1 + right_half_back + (down_half_back * row_size);
  2871.       if (!zflag)
  2872.     for (rr = 0; rr < 4; rr++) {
  2873.       index[0] = cm[((int) (rindex1[0] + rindex2[0]) >> 1) + blockvals[0]];
  2874.       index[1] = cm[((int) (rindex1[1] + rindex2[1]) >> 1) + blockvals[1]];
  2875.       index[2] = cm[((int) (rindex1[2] + rindex2[2]) >> 1) + blockvals[2]];
  2876.       index[3] = cm[((int) (rindex1[3] + rindex2[3]) >> 1) + blockvals[3]];
  2877.       index[4] = cm[((int) (rindex1[4] + rindex2[4]) >> 1) + blockvals[4]];
  2878.       index[5] = cm[((int) (rindex1[5] + rindex2[5]) >> 1) + blockvals[5]];
  2879.       index[6] = cm[((int) (rindex1[6] + rindex2[6]) >> 1) + blockvals[6]];
  2880.       index[7] = cm[((int) (rindex1[7] + rindex2[7]) >> 1) + blockvals[7]];
  2881.       index += row_size;
  2882.       rindex1 += row_size;
  2883.       rindex2 += row_size;
  2884.       
  2885.       index[0] = cm[((int) (rindex1[0] + rindex2[0]) >> 1) + blockvals[8]];
  2886.       index[1] = cm[((int) (rindex1[1] + rindex2[1]) >> 1) + blockvals[9]];
  2887.       index[2] = cm[((int) (rindex1[2] + rindex2[2]) >> 1) + blockvals[10]];
  2888.       index[3] = cm[((int) (rindex1[3] + rindex2[3]) >> 1) + blockvals[11]];
  2889.       index[4] = cm[((int) (rindex1[4] + rindex2[4]) >> 1) + blockvals[12]];
  2890.       index[5] = cm[((int) (rindex1[5] + rindex2[5]) >> 1) + blockvals[13]];
  2891.       index[6] = cm[((int) (rindex1[6] + rindex2[6]) >> 1) + blockvals[14]];
  2892.       index[7] = cm[((int) (rindex1[7] + rindex2[7]) >> 1) + blockvals[15]];
  2893.       blockvals += 16;
  2894.       index += row_size;
  2895.       rindex1 += row_size;
  2896.       rindex2 += row_size;
  2897.     }
  2898.       else
  2899.     for (rr = 0; rr < 4; rr++) {
  2900.       index[0] = (int) (rindex1[0] + rindex2[0]) >> 1;
  2901.       index[1] = (int) (rindex1[1] + rindex2[1]) >> 1;
  2902.       index[2] = (int) (rindex1[2] + rindex2[2]) >> 1;
  2903.       index[3] = (int) (rindex1[3] + rindex2[3]) >> 1;
  2904.       index[4] = (int) (rindex1[4] + rindex2[4]) >> 1;
  2905.       index[5] = (int) (rindex1[5] + rindex2[5]) >> 1;
  2906.       index[6] = (int) (rindex1[6] + rindex2[6]) >> 1;
  2907.       index[7] = (int) (rindex1[7] + rindex2[7]) >> 1;
  2908.       index += row_size;
  2909.       rindex1 += row_size;
  2910.       rindex2 += row_size;
  2911.       
  2912.       index[0] = (int) (rindex1[0] + rindex2[0]) >> 1;
  2913.       index[1] = (int) (rindex1[1] + rindex2[1]) >> 1;
  2914.       index[2] = (int) (rindex1[2] + rindex2[2]) >> 1;
  2915.       index[3] = (int) (rindex1[3] + rindex2[3]) >> 1;
  2916.       index[4] = (int) (rindex1[4] + rindex2[4]) >> 1;
  2917.       index[5] = (int) (rindex1[5] + rindex2[5]) >> 1;
  2918.       index[6] = (int) (rindex1[6] + rindex2[6]) >> 1;
  2919.       index[7] = (int) (rindex1[7] + rindex2[7]) >> 1;
  2920.       index += row_size;
  2921.       rindex1 += row_size;
  2922.       rindex2 += row_size;
  2923.     }
  2924.     }
  2925.  
  2926. #ifdef LOOSE_MPEG
  2927.   }
  2928. #endif
  2929.  
  2930. }
  2931.  
  2932.  
  2933. /*
  2934.  *--------------------------------------------------------------
  2935.  *
  2936.  * ReconBiMBlock --
  2937.  *
  2938.  *    Reconstructs bidirectionally predicted macroblocks.
  2939.  *
  2940.  * Results:
  2941.  *      None.
  2942.  *
  2943.  * Side effects:
  2944.  *      None.
  2945.  *
  2946.  *--------------------------------------------------------------
  2947.  */
  2948.  
  2949. static void
  2950. ReconBiMBlock(vid_stream, bnum, recon_right_for, recon_down_for,
  2951.           recon_right_back, recon_down_back, zflag)
  2952.   VidStream *vid_stream;
  2953.   int bnum, recon_right_for, recon_down_for, recon_right_back, recon_down_back;
  2954.   int zflag;
  2955. {
  2956.   int mb_row, mb_col, row, col, row_size, rr;
  2957.   unsigned char *dest, *past, *future;
  2958.   int right_for, down_for, right_half_for, down_half_for;
  2959.   int right_back, down_back, right_half_back, down_half_back;
  2960.   unsigned char *index, *rindex1, *bindex1;
  2961.   short int *blockvals;
  2962.   int forw_row_start, back_row_start, forw_col_start, back_col_start;
  2963.  
  2964. #ifdef LOOSE_MPEG
  2965.   int illegal_forw = 0;
  2966.   int illegal_back = 0;
  2967. #endif
  2968.  
  2969.   /* Calculate macroblock row and column from address. */
  2970.  
  2971.   mb_row = vid_stream->mblock.mb_address / vid_stream->mb_width;
  2972.   mb_col = vid_stream->mblock.mb_address % vid_stream->mb_width;
  2973.  
  2974.   /* If block is luminance block... */
  2975.  
  2976.   if (bnum < 4) {
  2977.  
  2978.     /*
  2979.      * Calculate right_for, down_for, right_half_for, down_half_for,
  2980.      * right_back, down_bakc, right_half_back, and down_half_back, motion
  2981.      * vectors.
  2982.      */
  2983.  
  2984.     right_for = recon_right_for >> 1;
  2985.     down_for = recon_down_for >> 1;
  2986.     right_half_for = recon_right_for & 0x1;
  2987.     down_half_for = recon_down_for & 0x1;
  2988.  
  2989.     right_back = recon_right_back >> 1;
  2990.     down_back = recon_down_back >> 1;
  2991.     right_half_back = recon_right_back & 0x1;
  2992.     down_half_back = recon_down_back & 0x1;
  2993.  
  2994.     /* Set dest to luminance plane of current pict image. */
  2995.  
  2996.     dest = vid_stream->current->luminance;
  2997.  
  2998.     /* If past frame exists, set past to luminance plane of past frame. */
  2999.  
  3000.     if (vid_stream->past != NULL)
  3001.       past = vid_stream->past->luminance;
  3002.  
  3003.     /*
  3004.      * If future frame exists, set future to luminance plane of future frame.
  3005.      */
  3006.  
  3007.     if (vid_stream->future != NULL)
  3008.       future = vid_stream->future->luminance;
  3009.  
  3010.     /* Establish row size. */
  3011.  
  3012.     row_size = (vid_stream->mb_width << 4);
  3013.  
  3014.     /* Calculate row,col of upper left pixel in block. */
  3015.  
  3016.     row = (mb_row << 4);
  3017.     col = (mb_col << 4);
  3018.     if (bnum > 1)
  3019.       row += 8;
  3020.     if (bnum & 0x01)
  3021.       col += 8;
  3022.  
  3023.     forw_col_start = col + right_for;
  3024.     forw_row_start = row + down_for;
  3025.  
  3026.     back_col_start = col + right_back;
  3027.     back_row_start = row + down_back;
  3028.  
  3029. #ifdef LOOSE_MPEG
  3030.  
  3031.     /* Check for illegal pred. blocks. */
  3032.  
  3033.  
  3034.     if (forw_col_start+8 > lmaxx) illegal_forw = 1;
  3035.     else if (forw_col_start < 0) illegal_forw = 1;
  3036.  
  3037.     if (forw_row_start+8 > lmaxy) illegal_forw = 1;
  3038.     else if (forw_row_start < 0) illegal_forw = 1;
  3039.  
  3040.     if (back_col_start+8 > lmaxx) illegal_back = 1;
  3041.     else if (back_col_start < 0) illegal_back = 1;
  3042.  
  3043.     if (back_row_start+8 > lmaxy) illegal_back = 1;
  3044.     else if (back_row_start < 0) illegal_back = 1;
  3045.  
  3046. #endif
  3047.  
  3048.   }
  3049.   /* Otherwise, block is NOT luminance block, ... */
  3050.  
  3051.   else {
  3052.  
  3053.     /* Construct motion vectors. */
  3054.  
  3055.     recon_right_for /= 2;
  3056.     recon_down_for /= 2;
  3057.     right_for = recon_right_for >> 1;
  3058.     down_for = recon_down_for >> 1;
  3059.     right_half_for = recon_right_for & 0x1;
  3060.     down_half_for = recon_down_for & 0x1;
  3061.  
  3062.     recon_right_back /= 2;
  3063.     recon_down_back /= 2;
  3064.     right_back = recon_right_back >> 1;
  3065.     down_back = recon_down_back >> 1;
  3066.     right_half_back = recon_right_back & 0x1;
  3067.     down_half_back = recon_down_back & 0x1;
  3068.  
  3069.     /* Establish row size. */
  3070.  
  3071.     row_size = (vid_stream->mb_width << 3);
  3072.  
  3073.     /* Calculate row,col of upper left pixel in block. */
  3074.  
  3075.     row = (mb_row << 3);
  3076.     col = (mb_col << 3);
  3077.  
  3078.     forw_col_start = col + right_for;
  3079.     forw_row_start = row + down_for;
  3080.  
  3081.     back_col_start = col + right_back;
  3082.     back_row_start = row + down_back;
  3083.  
  3084. #ifdef LOOSE_MPEG
  3085.  
  3086.     /* Check for illegal pred. blocks. */
  3087.  
  3088.     if (forw_col_start+8 > cmaxx) illegal_forw = 1;
  3089.     else if (forw_col_start < 0) illegal_forw = 1;
  3090.  
  3091.     if (forw_row_start+8 > cmaxy) illegal_forw = 1;
  3092.     else if (forw_row_start < 0) illegal_forw = 1;
  3093.  
  3094.     if (back_col_start+8 > cmaxx) illegal_back = 1;
  3095.     else if (back_col_start < 0) illegal_back = 1;
  3096.     
  3097.     if (back_row_start+8 > cmaxy) illegal_back = 1;
  3098.     else if (back_row_start < 0) illegal_back = 1;
  3099.  
  3100. #endif
  3101.     
  3102.     /* If block is Cr block... */
  3103.  
  3104.     if (bnum == 4) {
  3105.  
  3106.       /* Set dest to Cr plane of current pict image. */
  3107.  
  3108.       dest = vid_stream->current->Cr;
  3109.  
  3110.       /* If past frame exists, set past to Cr plane of past image. */
  3111.  
  3112.       if (vid_stream->past != NULL)
  3113.     past = vid_stream->past->Cr;
  3114.  
  3115.       /*
  3116.        * If future frame exists, set future to Cr plane of future image.
  3117.        */
  3118.  
  3119.       if (vid_stream->future != NULL)
  3120.     future = vid_stream->future->Cr;
  3121.     }
  3122.     /* Otherwise, block is Cb block... */
  3123.  
  3124.     else {
  3125.  
  3126.       /* Set dest to Cb plane of current pict image. */
  3127.  
  3128.       dest = vid_stream->current->Cb;
  3129.  
  3130.       /* If past frame exists, set past to Cb plane of past frame. */
  3131.  
  3132.       if (vid_stream->past != NULL)
  3133.     past = vid_stream->past->Cb;
  3134.  
  3135.       /*
  3136.        * If future frame exists, set future to Cb plane of future frame.
  3137.        */
  3138.  
  3139.       if (vid_stream->future != NULL)
  3140.     future = vid_stream->future->Cb;
  3141.     }
  3142.   }
  3143.  
  3144.   /* For each pixel in block... */
  3145.  
  3146.   index = dest + (row * row_size) + col;
  3147.  
  3148. #ifdef LOOSE_MPEG
  3149.   if (illegal_forw) 
  3150.     rindex1 = future + back_row_start * row_size + back_col_start;
  3151.   else 
  3152. #endif
  3153.     rindex1 = past + forw_row_start  * row_size + forw_col_start;
  3154.  
  3155. #ifdef LOOSE_MPEG
  3156.   if (illegal_back) 
  3157.     bindex1 = past + forw_row_start * row_size + forw_col_start;
  3158.   else 
  3159. #endif
  3160.     bindex1 = future + back_row_start * row_size + back_col_start;
  3161.  
  3162.   blockvals = (short int *) &(vid_stream->block.dct_recon[0][0]);
  3163.  
  3164.   {
  3165.   unsigned char *cm = cropTbl + MAX_NEG_CROP;
  3166.   if (!zflag)
  3167.     for (rr = 0; rr < 4; rr++) {
  3168.       index[0] = cm[((int) (rindex1[0] + bindex1[0]) >> 1) + blockvals[0]];
  3169.       index[1] = cm[((int) (rindex1[1] + bindex1[1]) >> 1) + blockvals[1]];
  3170.       index[2] = cm[((int) (rindex1[2] + bindex1[2]) >> 1) + blockvals[2]];
  3171.       index[3] = cm[((int) (rindex1[3] + bindex1[3]) >> 1) + blockvals[3]];
  3172.       index[4] = cm[((int) (rindex1[4] + bindex1[4]) >> 1) + blockvals[4]];
  3173.       index[5] = cm[((int) (rindex1[5] + bindex1[5]) >> 1) + blockvals[5]];
  3174.       index[6] = cm[((int) (rindex1[6] + bindex1[6]) >> 1) + blockvals[6]];
  3175.       index[7] = cm[((int) (rindex1[7] + bindex1[7]) >> 1) + blockvals[7]];
  3176.       index += row_size;
  3177.       rindex1 += row_size;
  3178.       bindex1 += row_size;
  3179.  
  3180.       index[0] = cm[((int) (rindex1[0] + bindex1[0]) >> 1) + blockvals[8]];
  3181.       index[1] = cm[((int) (rindex1[1] + bindex1[1]) >> 1) + blockvals[9]];
  3182.       index[2] = cm[((int) (rindex1[2] + bindex1[2]) >> 1) + blockvals[10]];
  3183.       index[3] = cm[((int) (rindex1[3] + bindex1[3]) >> 1) + blockvals[11]];
  3184.       index[4] = cm[((int) (rindex1[4] + bindex1[4]) >> 1) + blockvals[12]];
  3185.       index[5] = cm[((int) (rindex1[5] + bindex1[5]) >> 1) + blockvals[13]];
  3186.       index[6] = cm[((int) (rindex1[6] + bindex1[6]) >> 1) + blockvals[14]];
  3187.       index[7] = cm[((int) (rindex1[7] + bindex1[7]) >> 1) + blockvals[15]];
  3188.       blockvals += 16;
  3189.       index += row_size;
  3190.       rindex1 += row_size;
  3191.       bindex1 += row_size;
  3192.     }
  3193.  
  3194.   else
  3195.     for (rr = 0; rr < 4; rr++) {
  3196.       index[0] = (int) (rindex1[0] + bindex1[0]) >> 1;
  3197.       index[1] = (int) (rindex1[1] + bindex1[1]) >> 1;
  3198.       index[2] = (int) (rindex1[2] + bindex1[2]) >> 1;
  3199.       index[3] = (int) (rindex1[3] + bindex1[3]) >> 1;
  3200.       index[4] = (int) (rindex1[4] + bindex1[4]) >> 1;
  3201.       index[5] = (int) (rindex1[5] + bindex1[5]) >> 1;
  3202.       index[6] = (int) (rindex1[6] + bindex1[6]) >> 1;
  3203.       index[7] = (int) (rindex1[7] + bindex1[7]) >> 1;
  3204.       index += row_size;
  3205.       rindex1 += row_size;
  3206.       bindex1 += row_size;
  3207.  
  3208.       index[0] = (int) (rindex1[0] + bindex1[0]) >> 1;
  3209.       index[1] = (int) (rindex1[1] + bindex1[1]) >> 1;
  3210.       index[2] = (int) (rindex1[2] + bindex1[2]) >> 1;
  3211.       index[3] = (int) (rindex1[3] + bindex1[3]) >> 1;
  3212.       index[4] = (int) (rindex1[4] + bindex1[4]) >> 1;
  3213.       index[5] = (int) (rindex1[5] + bindex1[5]) >> 1;
  3214.       index[6] = (int) (rindex1[6] + bindex1[6]) >> 1;
  3215.       index[7] = (int) (rindex1[7] + bindex1[7]) >> 1;
  3216.       index += row_size;
  3217.       rindex1 += row_size;
  3218.       bindex1 += row_size;
  3219.     }
  3220.   }
  3221. }
  3222.  
  3223. /*
  3224.  *--------------------------------------------------------------
  3225.  *
  3226.  * ProcessSkippedPFrameMBlocks --
  3227.  *
  3228.  *    Processes skipped macroblocks in P frames.
  3229.  *
  3230.  * Results:
  3231.  *    Calculates pixel values for luminance, Cr, and Cb planes
  3232.  *      in current pict image for skipped macroblocks.
  3233.  *
  3234.  * Side effects:
  3235.  *    Pixel values in pict image changed.
  3236.  *
  3237.  *--------------------------------------------------------------
  3238.  */
  3239.  
  3240. static void
  3241. ProcessSkippedPFrameMBlocks(vid_stream)
  3242.   VidStream *vid_stream;
  3243. {
  3244.   int row_size, half_row, mb_row, mb_col, row, col, rr;
  3245.   int addr, row_incr, half_row_incr, crow, ccol;
  3246.   int *dest, *src, *dest1, *src1;
  3247.  
  3248.   /* Calculate row sizes for luminance and Cr/Cb macroblock areas. */
  3249.  
  3250.   row_size = vid_stream->mb_width << 4;
  3251.   half_row = (row_size >> 1);
  3252.   row_incr = row_size >> 2;
  3253.   half_row_incr = half_row >> 2;
  3254.  
  3255.   /* For each skipped macroblock, do... */
  3256.  
  3257.   for (addr = vid_stream->mblock.past_mb_addr + 1;
  3258.        addr < vid_stream->mblock.mb_address; addr++) {
  3259.  
  3260.     /* Calculate macroblock row and col. */
  3261.  
  3262.     mb_row = addr / vid_stream->mb_width;
  3263.     mb_col = addr % vid_stream->mb_width;
  3264.  
  3265.     /* Calculate upper left pixel row,col for luminance plane. */
  3266.  
  3267.     row = mb_row << 4;
  3268.     col = mb_col << 4;
  3269.  
  3270.  
  3271.     /* For each row in macroblock luminance plane... */
  3272.  
  3273.     dest = (int *)(vid_stream->current->luminance + (row * row_size) + col);
  3274.     src = (int *)(vid_stream->future->luminance + (row * row_size) + col);
  3275.  
  3276.     for (rr = 0; rr < 8; rr++) {
  3277.  
  3278.       /* Copy pixel values from last I or P picture. */
  3279.  
  3280.       dest[0] = src[0];
  3281.       dest[1] = src[1];
  3282.       dest[2] = src[2];
  3283.       dest[3] = src[3];
  3284.       dest += row_incr;
  3285.       src += row_incr;
  3286.  
  3287.       dest[0] = src[0];
  3288.       dest[1] = src[1];
  3289.       dest[2] = src[2];
  3290.       dest[3] = src[3];
  3291.       dest += row_incr;
  3292.       src += row_incr;
  3293.     }
  3294.  
  3295.     /*
  3296.      * Divide row,col to get upper left pixel of macroblock in Cr and Cb
  3297.      * planes.
  3298.      */
  3299.  
  3300.     crow = row >> 1;
  3301.     ccol = col >> 1;
  3302.  
  3303.     /* For each row in Cr, and Cb planes... */
  3304.  
  3305.     dest = (int *)(vid_stream->current->Cr + (crow * half_row) + ccol);
  3306.     src = (int *)(vid_stream->future->Cr + (crow * half_row) + ccol);
  3307.     dest1 = (int *)(vid_stream->current->Cb + (crow * half_row) + ccol);
  3308.     src1 = (int *)(vid_stream->future->Cb + (crow * half_row) + ccol);
  3309.  
  3310.     for (rr = 0; rr < 4; rr++) {
  3311.  
  3312.       /* Copy pixel values from last I or P picture. */
  3313.  
  3314.       dest[0] = src[0];
  3315.       dest[1] = src[1];
  3316.  
  3317.       dest1[0] = src1[0];
  3318.       dest1[1] = src1[1];
  3319.  
  3320.       dest += half_row_incr;
  3321.       src += half_row_incr;
  3322.       dest1 += half_row_incr;
  3323.       src1 += half_row_incr;
  3324.  
  3325.       dest[0] = src[0];
  3326.       dest[1] = src[1];
  3327.  
  3328.       dest1[0] = src1[0];
  3329.       dest1[1] = src1[1];
  3330.  
  3331.       dest += half_row_incr;
  3332.       src += half_row_incr;
  3333.       dest1 += half_row_incr;
  3334.       src1 += half_row_incr;
  3335.     }
  3336.  
  3337.     if (ditherType == MBORDERED_DITHER) {
  3338. #if 0
  3339.       MBOrderedDitherDisplayCopy(vid_stream, addr,
  3340.                  1, 0, 0, 0, 0, 0,
  3341.                  vid_stream->future->display,
  3342.                  (unsigned char *) NULL);
  3343. #endif
  3344.       ditherFlags[addr] = 0;
  3345.     }
  3346.   }
  3347.  
  3348.   vid_stream->mblock.recon_right_for_prev = 0;
  3349.   vid_stream->mblock.recon_down_for_prev = 0;
  3350. }
  3351.  
  3352.  
  3353.  
  3354.  
  3355. /*
  3356.  *--------------------------------------------------------------
  3357.  *
  3358.  * ProcessSkippedBFrameMBlocks --
  3359.  *
  3360.  *    Processes skipped macroblocks in B frames.
  3361.  *
  3362.  * Results:
  3363.  *    Calculates pixel values for luminance, Cr, and Cb planes
  3364.  *      in current pict image for skipped macroblocks.
  3365.  *
  3366.  * Side effects:
  3367.  *    Pixel values in pict image changed.
  3368.  *
  3369.  *--------------------------------------------------------------
  3370.  */
  3371.  
  3372. static void
  3373. ProcessSkippedBFrameMBlocks(vid_stream)
  3374.   VidStream *vid_stream;
  3375. {
  3376.   int row_size, half_row, mb_row, mb_col, row, col, rr;
  3377.   int right_half_for, down_half_for, c_right_half_for, c_down_half_for;
  3378.   int right_half_back, down_half_back, c_right_half_back, c_down_half_back;
  3379.   int addr, right_for, down_for;
  3380.   int recon_right_for, recon_down_for;
  3381.   int recon_right_back, recon_down_back;
  3382.   int right_back, down_back;
  3383.   int c_right_for, c_down_for;
  3384.   int c_right_back, c_down_back;
  3385.   unsigned char forw_lum[256];
  3386.   unsigned char forw_cr[64], forw_cb[64];
  3387.   unsigned char back_lum[256], back_cr[64], back_cb[64];
  3388.   int row_incr, half_row_incr;
  3389.   int ccol, crow;
  3390.  
  3391.   /* Calculate row sizes for luminance and Cr/Cb macroblock areas. */
  3392.  
  3393.   row_size = vid_stream->mb_width << 4;
  3394.   half_row = (row_size >> 1);
  3395.   row_incr = row_size >> 2;
  3396.   half_row_incr =  half_row >> 2;
  3397.  
  3398.   /* Establish motion vector codes based on full pixel flag. */
  3399.  
  3400.   if (vid_stream->picture.full_pel_forw_vector) {
  3401.     recon_right_for = vid_stream->mblock.recon_right_for_prev << 1;
  3402.     recon_down_for = vid_stream->mblock.recon_down_for_prev << 1;
  3403.   } else {
  3404.     recon_right_for = vid_stream->mblock.recon_right_for_prev;
  3405.     recon_down_for = vid_stream->mblock.recon_down_for_prev;
  3406.   }
  3407.  
  3408.   if (vid_stream->picture.full_pel_back_vector) {
  3409.     recon_right_back = vid_stream->mblock.recon_right_back_prev << 1;
  3410.     recon_down_back = vid_stream->mblock.recon_down_back_prev << 1;
  3411.   } else {
  3412.     recon_right_back = vid_stream->mblock.recon_right_back_prev;
  3413.     recon_down_back = vid_stream->mblock.recon_down_back_prev;
  3414.   }
  3415.  
  3416.  
  3417.   /* If only one motion vector, do display copy, else do full
  3418.      calculation. 
  3419.   */
  3420.  
  3421.   if (ditherType == MBORDERED_DITHER) {
  3422.     if (vid_stream->mblock.bpict_past_forw &&
  3423.     !vid_stream->mblock.bpict_past_back) {
  3424.       for (addr = vid_stream->mblock.past_mb_addr+1;
  3425.        addr < vid_stream->mblock.mb_address; addr++) {
  3426. #if 0    
  3427.     MBOrderedDitherDisplayCopy(vid_stream, addr,
  3428.                    1, recon_right_for, recon_down_for,
  3429.                  0, 0, 0, vid_stream->past->display,
  3430.                    vid_stream->future->display);
  3431. #endif
  3432.     ditherFlags[addr] = 0;
  3433.       }
  3434.       return;
  3435.     }
  3436.     if (vid_stream->mblock.bpict_past_back && 
  3437.     !vid_stream->mblock.bpict_past_forw) {
  3438.       for (addr = vid_stream->mblock.past_mb_addr+1;
  3439.        addr < vid_stream->mblock.mb_address; addr++) {
  3440. #if 0
  3441.     
  3442.     MBOrderedDitherDisplayCopy(vid_stream, addr,
  3443.                    0, 0, 0,
  3444.                    1, recon_right_back, recon_down_back,
  3445.                    vid_stream->past->display, vid_stream->future->display);
  3446. #endif
  3447.     ditherFlags[addr] = 0;
  3448.  
  3449.       }
  3450.       return;
  3451.     }
  3452.   }
  3453.  
  3454.   /* Calculate motion vectors. */
  3455.   
  3456.   if (vid_stream->mblock.bpict_past_forw) {
  3457.     right_for = recon_right_for >> 1;
  3458.     down_for = recon_down_for >> 1;
  3459.     right_half_for = recon_right_for & 0x1;
  3460.     down_half_for = recon_down_for & 0x1;
  3461.     
  3462.     recon_right_for /= 2;
  3463.     recon_down_for /= 2;
  3464.     c_right_for = recon_right_for >> 1;
  3465.     c_down_for = recon_down_for >> 1;
  3466.     c_right_half_for = recon_right_for & 0x1;
  3467.     c_down_half_for = recon_down_for & 0x1;
  3468.     
  3469.   }
  3470.   if (vid_stream->mblock.bpict_past_back) {
  3471.     right_back = recon_right_back >> 1;
  3472.     down_back = recon_down_back >> 1;
  3473.     right_half_back = recon_right_back & 0x1;
  3474.     down_half_back = recon_down_back & 0x1;
  3475.     
  3476.     recon_right_back /= 2;
  3477.     recon_down_back /= 2;
  3478.     c_right_back = recon_right_back >> 1;
  3479.     c_down_back = recon_down_back >> 1;
  3480.     c_right_half_back = recon_right_back & 0x1;
  3481.     c_down_half_back = recon_down_back & 0x1;
  3482.     
  3483.   }
  3484.   /* For each skipped macroblock, do... */
  3485.   
  3486.   for (addr = vid_stream->mblock.past_mb_addr + 1;
  3487.        addr < vid_stream->mblock.mb_address; addr++) {
  3488.     
  3489.     /* Calculate macroblock row and col. */
  3490.     
  3491.     mb_row = addr / vid_stream->mb_width;
  3492.     mb_col = addr % vid_stream->mb_width;
  3493.     
  3494.     /* Calculate upper left pixel row,col for luminance plane. */
  3495.     
  3496.     row = mb_row << 4;
  3497.     col = mb_col << 4;
  3498.     crow = row / 2;
  3499.     ccol = col / 2;
  3500.     
  3501.     /* If forward predicted, calculate prediction values. */
  3502.     
  3503.     if (vid_stream->mblock.bpict_past_forw) {
  3504.       
  3505.       ReconSkippedBlock(vid_stream->past->luminance, forw_lum,
  3506.             row, col, row_size, right_for, down_for,
  3507.             right_half_for, down_half_for, 16);
  3508.       ReconSkippedBlock(vid_stream->past->Cr, forw_cr, crow,
  3509.             ccol, half_row,
  3510.             c_right_for, c_down_for, c_right_half_for, c_down_half_for, 8);
  3511.       ReconSkippedBlock(vid_stream->past->Cb, forw_cb, crow,
  3512.             ccol, half_row,
  3513.             c_right_for, c_down_for, c_right_half_for, c_down_half_for, 8);
  3514.     }
  3515.     /* If back predicted, calculate prediction values. */
  3516.     
  3517.     if (vid_stream->mblock.bpict_past_back) {
  3518.       ReconSkippedBlock(vid_stream->future->luminance, back_lum,
  3519.             row, col, row_size, right_back, down_back,
  3520.             right_half_back, down_half_back, 16);
  3521.       ReconSkippedBlock(vid_stream->future->Cr, back_cr, crow,
  3522.             ccol, half_row,
  3523.             c_right_back, c_down_back,
  3524.             c_right_half_back, c_down_half_back, 8);
  3525.       ReconSkippedBlock(vid_stream->future->Cb, back_cb, crow,
  3526.             ccol, half_row,
  3527.             c_right_back, c_down_back,
  3528.             c_right_half_back, c_down_half_back, 8);
  3529.     }
  3530.     if (vid_stream->mblock.bpict_past_forw &&
  3531.     !vid_stream->mblock.bpict_past_back) {
  3532.       
  3533.       int *dest, *dest1;
  3534.       int *src, *src1;
  3535.       dest = (int *)(vid_stream->current->luminance + (row * row_size) + col);
  3536.       src = (int *)forw_lum;
  3537.       
  3538.       for (rr = 0; rr < 16; rr++) {
  3539.     
  3540.     /* memcpy(dest, forw_lum+(rr<<4), 16);  */
  3541.     dest[0] = src[0];
  3542.     dest[1] = src[1];
  3543.     dest[2] = src[2];
  3544.     dest[3] = src[3];
  3545.     dest += row_incr;
  3546.     src += 4;
  3547.       }
  3548.       
  3549.       dest = (int *)(vid_stream->current->Cr + (crow * half_row) + ccol);
  3550.       dest1 = (int *)(vid_stream->current->Cb + (crow * half_row) + ccol);
  3551.       src = (int *)forw_cr;
  3552.       src1 = (int *)forw_cb;
  3553.       
  3554.       for (rr = 0; rr < 8; rr++) {
  3555.     /*
  3556.      * memcpy(dest, forw_cr+(rr<<3), 8); memcpy(dest1, forw_cb+(rr<<3),
  3557.      * 8);
  3558.      */
  3559.     
  3560.     dest[0] = src[0];
  3561.     dest[1] = src[1];
  3562.     
  3563.     dest1[0] = src1[0];
  3564.     dest1[1] = src1[1];
  3565.     
  3566.     dest += half_row_incr;
  3567.     dest1 += half_row_incr;
  3568.     src += 2;
  3569.     src1 += 2;
  3570.       }
  3571.     } else if (vid_stream->mblock.bpict_past_back &&
  3572.            !vid_stream->mblock.bpict_past_forw) {
  3573.       
  3574.       int *src, *src1;
  3575.       int *dest, *dest1;
  3576.       dest = (int *)(vid_stream->current->luminance + (row * row_size) + col);
  3577.       src = (int *)back_lum;
  3578.       
  3579.       for (rr = 0; rr < 16; rr++) {
  3580.     dest[0] = src[0];
  3581.     dest[1] = src[1];
  3582.     dest[2] = src[2];
  3583.     dest[3] = src[3];
  3584.     dest += row_incr;
  3585.     src += 4;
  3586.       }
  3587.       
  3588.       
  3589.       dest = (int *)(vid_stream->current->Cr + (crow * half_row) + ccol);
  3590.       dest1 = (int *)(vid_stream->current->Cb + (crow * half_row) + ccol);
  3591.       src = (int *)back_cr;
  3592.       src1 = (int *)back_cb;
  3593.       
  3594.       for (rr = 0; rr < 8; rr++) {
  3595.     /*
  3596.      * memcpy(dest, back_cr+(rr<<3), 8); memcpy(dest1, back_cb+(rr<<3),
  3597.      * 8);
  3598.      */
  3599.     
  3600.     dest[0] = src[0];
  3601.     dest[1] = src[1];
  3602.     
  3603.     dest1[0] = src1[0];
  3604.     dest1[1] = src1[1];
  3605.     
  3606.     dest += half_row_incr;
  3607.     dest1 += half_row_incr;
  3608.     src += 2;
  3609.     src1 += 2;
  3610.       }
  3611.     } else {
  3612.       
  3613.       unsigned char *src1, *src2, *src1a, *src2a;
  3614.       unsigned char *dest, *dest1;
  3615.       dest = vid_stream->current->luminance + (row * row_size) + col;
  3616.       src1 = forw_lum;
  3617.       src2 = back_lum;
  3618.       
  3619.       for (rr = 0; rr < 16; rr++) {
  3620.     dest[0] = (int) (src1[0] + src2[0]) >> 1;
  3621.     dest[1] = (int) (src1[1] + src2[1]) >> 1;
  3622.     dest[2] = (int) (src1[2] + src2[2]) >> 1;
  3623.     dest[3] = (int) (src1[3] + src2[3]) >> 1;
  3624.     dest[4] = (int) (src1[4] + src2[4]) >> 1;
  3625.     dest[5] = (int) (src1[5] + src2[5]) >> 1;
  3626.     dest[6] = (int) (src1[6] + src2[6]) >> 1;
  3627.     dest[7] = (int) (src1[7] + src2[7]) >> 1;
  3628.     dest[8] = (int) (src1[8] + src2[8]) >> 1;
  3629.     dest[9] = (int) (src1[9] + src2[9]) >> 1;
  3630.     dest[10] = (int) (src1[10] + src2[10]) >> 1;
  3631.     dest[11] = (int) (src1[11] + src2[11]) >> 1;
  3632.     dest[12] = (int) (src1[12] + src2[12]) >> 1;
  3633.     dest[13] = (int) (src1[13] + src2[13]) >> 1;
  3634.     dest[14] = (int) (src1[14] + src2[14]) >> 1;
  3635.     dest[15] = (int) (src1[15] + src2[15]) >> 1;
  3636.     dest += row_size;
  3637.     src1 += 16;
  3638.     src2 += 16;
  3639.       }
  3640.       
  3641.       
  3642.       dest = vid_stream->current->Cr + (crow * half_row) + ccol;
  3643.       dest1 = vid_stream->current->Cb + (crow * half_row) + ccol;
  3644.       src1 = forw_cr;
  3645.       src2 = back_cr;
  3646.       src1a = forw_cb;
  3647.       src2a = back_cb;
  3648.       
  3649.       for (rr = 0; rr < 8; rr++) {
  3650.     dest[0] = (int) (src1[0] + src2[0]) >> 1;
  3651.     dest[1] = (int) (src1[1] + src2[1]) >> 1;
  3652.     dest[2] = (int) (src1[2] + src2[2]) >> 1;
  3653.     dest[3] = (int) (src1[3] + src2[3]) >> 1;
  3654.     dest[4] = (int) (src1[4] + src2[4]) >> 1;
  3655.     dest[5] = (int) (src1[5] + src2[5]) >> 1;
  3656.     dest[6] = (int) (src1[6] + src2[6]) >> 1;
  3657.     dest[7] = (int) (src1[7] + src2[7]) >> 1;
  3658.     dest += half_row;
  3659.     src1 += 8;
  3660.     src2 += 8;
  3661.     
  3662.     dest1[0] = (int) (src1a[0] + src2a[0]) >> 1;
  3663.     dest1[1] = (int) (src1a[1] + src2a[1]) >> 1;
  3664.     dest1[2] = (int) (src1a[2] + src2a[2]) >> 1;
  3665.     dest1[3] = (int) (src1a[3] + src2a[3]) >> 1;
  3666.     dest1[4] = (int) (src1a[4] + src2a[4]) >> 1;
  3667.     dest1[5] = (int) (src1a[5] + src2a[5]) >> 1;
  3668.     dest1[6] = (int) (src1a[6] + src2a[6]) >> 1;
  3669.     dest1[7] = (int) (src1a[7] + src2a[7]) >> 1;
  3670.     dest1 += half_row;
  3671.     src1a += 8;
  3672.     src2a += 8;
  3673.       }
  3674.     }
  3675.     
  3676.     if (ditherType == MBORDERED_DITHER) {
  3677.       ditherFlags[addr] = 1;
  3678.     }
  3679.   }
  3680. }
  3681.  
  3682.  
  3683.  
  3684.  
  3685. /*
  3686.  *--------------------------------------------------------------
  3687.  *
  3688.  * ReconSkippedBlock --
  3689.  *
  3690.  *    Reconstructs predictive block for skipped macroblocks
  3691.  *      in B Frames.
  3692.  *
  3693.  * Results:
  3694.  *    No return values.
  3695.  *
  3696.  * Side effects:
  3697.  *    None.
  3698.  *
  3699.  *--------------------------------------------------------------
  3700.  */
  3701.  
  3702. static void
  3703. ReconSkippedBlock(source, dest, row, col, row_size,
  3704.           right, down, right_half, down_half, width)
  3705.   unsigned char *source;
  3706.   unsigned char *dest;
  3707.   int row, col, row_size, right, down, right_half, down_half, width;
  3708. {
  3709.   int rr;
  3710.   unsigned char *source2;
  3711.  
  3712.   source += ((row + down) * row_size) + col + right;
  3713.  
  3714.   if (width == 16) {
  3715.     if ((!right_half) && (!down_half)) {
  3716.     if (right & 0x1) {
  3717.       /* No alignment, use bye copy */
  3718.       for (rr = 0; rr < 16; rr++) {
  3719.         dest[0] = source[0];
  3720.         dest[1] = source[1];
  3721.         dest[2] = source[2];
  3722.         dest[3] = source[3];
  3723.         dest[4] = source[4];
  3724.         dest[5] = source[5];
  3725.         dest[6] = source[6];
  3726.         dest[7] = source[7];
  3727.         dest[8] = source[8];
  3728.         dest[9] = source[9];
  3729.         dest[10] = source[10];
  3730.         dest[11] = source[11];
  3731.         dest[12] = source[12];
  3732.         dest[13] = source[13];
  3733.         dest[14] = source[14];
  3734.         dest[15] = source[15];
  3735.         dest += 16;
  3736.         source += row_size;
  3737.       }
  3738.     } else if (right & 0x2) {
  3739.       /* Half-word bit aligned, use 16 bit copy */
  3740.       short *src = (short *)source;
  3741.       short *d = (short *)dest;
  3742.       row_size >>= 1;
  3743.       for (rr = 0; rr < 16; rr++) {
  3744.         d[0] = src[0];
  3745.         d[1] = src[1];
  3746.         d[2] = src[2];
  3747.         d[3] = src[3];
  3748.         d[4] = src[4];
  3749.         d[5] = src[5];
  3750.         d[6] = src[6];
  3751.         d[7] = src[7];
  3752.         d += 8;
  3753.         src += row_size;
  3754.       }
  3755.     } else {
  3756.       /* Word aligned, use 32 bit copy */
  3757.       int *src = (int *)source;
  3758.       int *d = (int *)dest;
  3759.       row_size >>= 2;
  3760.       for (rr = 0; rr < 16; rr++) {
  3761.         d[0] = src[0];
  3762.         d[1] = src[1];
  3763.         d[2] = src[2];
  3764.         d[3] = src[3];
  3765.         d += 4;
  3766.         src += row_size;
  3767.       }
  3768.     }
  3769.     } else {
  3770.       source2 = source + right_half + (row_size * down_half);
  3771.       for (rr = 0; rr < width; rr++) {
  3772.     dest[0] = (int) (source[0] + source2[0]) >> 1;
  3773.     dest[1] = (int) (source[1] + source2[1]) >> 1;
  3774.     dest[2] = (int) (source[2] + source2[2]) >> 1;
  3775.     dest[3] = (int) (source[3] + source2[3]) >> 1;
  3776.     dest[4] = (int) (source[4] + source2[4]) >> 1;
  3777.     dest[5] = (int) (source[5] + source2[5]) >> 1;
  3778.     dest[6] = (int) (source[6] + source2[6]) >> 1;
  3779.     dest[7] = (int) (source[7] + source2[7]) >> 1;
  3780.     dest[8] = (int) (source[8] + source2[8]) >> 1;
  3781.     dest[9] = (int) (source[9] + source2[9]) >> 1;
  3782.     dest[10] = (int) (source[10] + source2[10]) >> 1;
  3783.     dest[11] = (int) (source[11] + source2[11]) >> 1;
  3784.     dest[12] = (int) (source[12] + source2[12]) >> 1;
  3785.     dest[13] = (int) (source[13] + source2[13]) >> 1;
  3786.     dest[14] = (int) (source[14] + source2[14]) >> 1;
  3787.     dest[15] = (int) (source[15] + source2[15]) >> 1;
  3788.     dest += width;
  3789.     source += row_size;
  3790.     source2 += row_size;
  3791.       }
  3792.     }
  3793.   } else {            /* (width == 8) */
  3794.     assert(width == 8);
  3795.     if ((!right_half) && (!down_half)) {
  3796.       if (right & 0x1) {
  3797.     for (rr = 0; rr < width; rr++) {
  3798.       dest[0] = source[0];
  3799.       dest[1] = source[1];
  3800.       dest[2] = source[2];
  3801.       dest[3] = source[3];
  3802.       dest[4] = source[4];
  3803.       dest[5] = source[5];
  3804.       dest[6] = source[6];
  3805.       dest[7] = source[7];
  3806.       dest += 8;
  3807.       source += row_size;
  3808.     }
  3809.       } else if (right & 0x02) {
  3810.     short *d = (short *)dest;
  3811.     short *src = (short *)source;
  3812.     row_size >>= 1;
  3813.     for (rr = 0; rr < width; rr++) {
  3814.       d[0] = src[0];
  3815.       d[1] = src[1];
  3816.       d[2] = src[2];
  3817.       d[3] = src[3];
  3818.       d += 4;
  3819.       src += row_size;
  3820.     }
  3821.       } else {
  3822.     int *d = (int *)dest;
  3823.     int *src = (int *)source;
  3824.     row_size >>= 2;
  3825.     for (rr = 0; rr < width; rr++) {
  3826.       d[0] = src[0];
  3827.       d[1] = src[1];
  3828.       d += 2;
  3829.       src += row_size;
  3830.     }
  3831.       }
  3832.     } else {
  3833.       source2 = source + right_half + (row_size * down_half);
  3834.       for (rr = 0; rr < width; rr++) {
  3835.     dest[0] = (int) (source[0] + source2[0]) >> 1;
  3836.     dest[1] = (int) (source[1] + source2[1]) >> 1;
  3837.     dest[2] = (int) (source[2] + source2[2]) >> 1;
  3838.     dest[3] = (int) (source[3] + source2[3]) >> 1;
  3839.     dest[4] = (int) (source[4] + source2[4]) >> 1;
  3840.     dest[5] = (int) (source[5] + source2[5]) >> 1;
  3841.     dest[6] = (int) (source[6] + source2[6]) >> 1;
  3842.     dest[7] = (int) (source[7] + source2[7]) >> 1;
  3843.     dest += width;
  3844.     source += row_size;
  3845.     source2 += row_size;
  3846.       }
  3847.     }
  3848.   }
  3849. }
  3850.  
  3851.  
  3852.  
  3853. /*
  3854.  *--------------------------------------------------------------
  3855.  *
  3856.  * DoPictureDisplay --
  3857.  *
  3858.  *    Converts image from Lum, Cr, Cb to colormap space. Puts
  3859.  *      image in lum plane. Updates past and future frame
  3860.  *      pointers. Dithers image. Sends to display mechanism.
  3861.  *
  3862.  * Results:
  3863.  *    Pict image structure locked if displaying or if frame
  3864.  *      is needed as past or future reference.
  3865.  *
  3866.  * Side effects:
  3867.  *    Lum plane pummelled.
  3868.  *
  3869.  *--------------------------------------------------------------
  3870.  */
  3871.  
  3872. static int
  3873. DoPictureDisplay(vid_stream)
  3874.   VidStream *vid_stream;
  3875. {
  3876.  
  3877.   /* Convert to colormap space and dither. */
  3878.  
  3879.   DoDitherImage(vid_stream->current->luminance, vid_stream->current->Cr,
  3880.         vid_stream->current->Cb, vid_stream->current->display,
  3881.         vid_stream->mb_height * 16, vid_stream->mb_width * 16);
  3882.  
  3883.   /* Update past and future references if needed. */
  3884.  
  3885.   if ((vid_stream->picture.code_type == I_TYPE) || 
  3886.     (vid_stream->picture.code_type == P_TYPE)) {
  3887.     if (vid_stream->future == NULL) {
  3888.       vid_stream->future = vid_stream->current;
  3889.       vid_stream->future->locked |= FUTURE_LOCK;
  3890.     } else {
  3891.       if (vid_stream->past != NULL) {
  3892.     vid_stream->past->locked &= ~PAST_LOCK;
  3893.       }
  3894.       vid_stream->past = vid_stream->future;
  3895.       vid_stream->past->locked &= ~FUTURE_LOCK;
  3896.       vid_stream->past->locked |= PAST_LOCK;
  3897.       vid_stream->future = vid_stream->current;
  3898.       vid_stream->future->locked |= FUTURE_LOCK;
  3899.       vid_stream->current = vid_stream->past;
  3900. #if 0
  3901.       ExecuteDisplay(vid_stream);
  3902. #else
  3903.       return 1;
  3904. #endif
  3905.     }
  3906.   }
  3907.   else
  3908.   {
  3909. #if 0
  3910.     ExecuteDisplay(vid_stream);
  3911. #else
  3912.     return 1;
  3913. #endif
  3914.   }
  3915.    return 0;
  3916. }
  3917.  
  3918.  
  3919. /*
  3920.  *--------------------------------------------------------------
  3921.  *
  3922.  * ToggleBFlag --
  3923.  *
  3924.  *    Called to set no b frame processing flag.
  3925.  *
  3926.  * Results:
  3927.  *      No_B_Flag flag is toggled from present value to opposite value.
  3928.  *
  3929.  * Side effects:
  3930.  *      None.
  3931.  *
  3932.  *--------------------------------------------------------------
  3933.  */
  3934.  
  3935. void
  3936. ToggleBFlag()
  3937. {
  3938.   if (No_B_Flag) {
  3939.     No_B_Flag = 0;
  3940.   } else
  3941.     No_B_Flag = 1;
  3942. }
  3943.  
  3944.  
  3945.  
  3946.  
  3947. /*
  3948.  *--------------------------------------------------------------
  3949.  *
  3950.  * TogglePFlag --
  3951.  *
  3952.  *    Called to set no p frame processing flag.
  3953.  *
  3954.  * Results:
  3955.  *      No_P_Flag flag is toggled from present value to opposite value.
  3956.  *
  3957.  * Side effects:
  3958.  *      None.
  3959.  *
  3960.  *--------------------------------------------------------------
  3961.  */
  3962.  
  3963. void
  3964. TogglePFlag()
  3965. {
  3966.   if (No_P_Flag) {
  3967.     No_P_Flag = 0;
  3968.   } else
  3969.     No_P_Flag = 1;
  3970. }
  3971.